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 pearl-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
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
$)
26 CONST MaxOpCodeBase
= 3
27 CONST MaxOpCodeType
= 8
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 :)
39 OPEN
"I", 1, "insns.dat"
40 OPEN
"B", 3, "insns.tmp"
43 crlf$
= CHR
$(13) + CHR
$(10)
47 ' preprocessing the current file
50 HexChar$
= "0123456789ABCDEF"
52 PRINT
"Preprocessing INSNS.DAT"
59 IF (lineNr
AND 15) = 0 THEN
61 PRINT lineNr
, OpCodes
, OpCodeDebug
;
65 CALL StrSplitString(l
$, ";", LineData
$(), SplitCount
)
67 LineData
$(1) = StrTrim
$(LineData$(1), CHR
$(9) + " ")
68 IF LEN(LineData
$(1)) THEN
69 CALL StrSplitString(LineData
$(1), " ", StrucData
$(), cntSplit
)
71 PRINT
"line"; lineNr
; " does not contain four fields"
75 tst$
= UCASE
$(StrucData$(2))
80 p
= StrInstrLeft(1, tst$
+ ",", "|:,")
82 h$
= ReplaceOp
$(MID$(tst$, op
, p
- op
))
84 SELECT CASE MID$(tst$, p
, 1)
89 res$
= res$
+ "|" + h$
94 res$
= res$
+ h$
+ ","
96 res$
= res$
+ "|" + h$
+ ","
104 res$
= res$
+ "|" + h$
108 res$
= res$
+ h$
+ "|COLON,"
113 p
= StrInstrLeft(op
, tst$
+ ",", "|:,")
115 FOR a
= cnt
% + 1 TO 3
119 IF LEFT
$(res$, 2) = "0," THEN cnt
% = cnt
% - 1
120 StrucData
$(5) = LTRIM
$(STR$(cnt%))
124 tst$
= UCASE
$(StrucData$(4))
126 p
= INSTR(tst$
+ ",", ",")
129 h$
= MID$(tst$, op
, p
- op
)
134 res$
= res$
+ "IF_" + h$
136 res$
= res$
+ "|IF_" + h$
141 p
= INSTR(op
, tst$
+ ",", ",")
145 tst$
= UCASE
$(StrucData$(3))
150 OpCodeDebug
= OpCodeDebug
+ 1 ' don't forget to increment
159 p
= INSTR(tst$
+ "\", "\")
161 h$
= MID$(tst$, op
, p
- op
)
162 IF LEFT
$(h$, 1) = "X" THEN
163 opCodeVal$
= CHR
$(VAL("&H" + MID$(h$, 2)))
170 opCodeVal$
= CHR
$(&H7) + CHR
$(&H17) + CHR
$(&H1F)
173 opCodeVal$
= CHR
$(&HA1) + CHR
$(&HA9)
176 opCodeVal$
= CHR
$(&H6) + CHR
$(&HE) + CHR
$(&H16) + CHR
$(&H1E)
179 opCodeVal$
= CHR
$(&HA0) + CHR
$(&HA8)
181 CASE "10", "11", "12"
183 AddRegs
= VAL(h
$) - 9
186 AddCCode
= VAL(h
$) - 329
192 PRINT
"Line:"; lineNr
193 PRINT
"Unknown value: " + h$
199 p
= INSTR(op
, tst$
+ "\", "\")
202 PRINT
"No opcode found in line"; lineNr
209 FOR a
= 1 TO LEN(opCodeVal
$)
210 h
= ASC(MID$(opCodeVal$, a
, 1))
211 OpCodeStr$
= MKI
$(OpCodeDebug)
220 OpCodeList
$(h + b
) = OpCodeList
$(h + b
) + OpCodeStr$
223 OpCodeDebug
= OpCodeDebug
+ 1
227 OpCodes
= OpCodes
+ 1
228 LineOfs$
= LineOfs$
+ MKL
$(NowLineOfs&)
231 PUT #
3, NowLineOfs
&, h$
232 NowLineOfs
& = NowLineOfs
& + 1
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
240 LineOfs$
= LineOfs$
+ MKI
$(LineLg)
245 PRINT lineNr
, OpCodes
, OpCodeDebug
253 PRINT
"Creating INSNSA.C"
255 OPEN
"O", 2, "insnsa.c"
256 strBegStart$
= "static struct itemplate instrux_"
257 strBegEnd$
= "[] = {"
258 strEnd$
= " {-1}" + crlf$
+ "};" + crlf$
260 PRINT #
2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
262 PRINT #
2, "#include <stdio.h>"
263 PRINT #
2, "#include " + qt$
+ "nasm.h" + qt$
264 PRINT #
2, "#include " + qt$
+ "insns.h" + qt$
270 LineOfs
& = CVL(MID$(LineOfs$, pOfs
, 4))
271 l$
= SPACE
$(CVI(MID$(LineOfs$, pOfs
+ 4, 2)))
275 ' split data into fields
276 NoDebug
= ASC(LEFT
$(l$, 1))
279 lgLn
= ASC(MID$(l$, pLn
, 1))
280 StrucData
$(b) = MID$(l$, pLn
+ 1, lgLn
)
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)
290 SELECT CASE UCASE
$(StrucData$(3))
293 PRINT #
2, " {I_" + oldOpCode$
+ ", " + StrucData
$(5) + ", {" + StrucData
$(2) + "}, " + qt$
+ StrucData
$(3) + qt$
+ ", " + StrucData
$(4) + "},"
296 IF LEN(oldOpCode
$) THEN PRINT #
2, strEnd$
298 PRINT #
2, "struct itemplate *nasm_instructions[] = {"
300 p
= INSTR(Instructs
$, CHR
$(0))
302 h$
= MID$(Instructs$, op
, p
- op
)
303 PRINT #
2, " instrux_" + h$
+ ","
305 p
= INSTR(op
, Instructs
$, CHR
$(0))
318 PRINT
"Creating INSNSD.C"
320 OPEN
"O", 2, "insnsd.c"
322 PRINT #
2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
324 PRINT #
2, "#include <stdio.h>"
325 PRINT #
2, "#include " + qt$
+ "nasm.h" + qt$
326 PRINT #
2, "#include " + qt$
+ "insns.h" + qt$
330 PRINT #
2, "static struct itemplate instrux[] = {"
333 LineOfs
& = CVL(MID$(LineOfs$, pOfs
, 4))
334 l$
= SPACE
$(CVI(MID$(LineOfs$, pOfs
+ 4, 2)))
338 ' split data into fields
339 NoDebug
= ASC(LEFT
$(l$, 1))
342 lgLn
= ASC(MID$(l$, pLn
, 1))
343 StrucData
$(b) = MID$(l$, pLn
+ 1, lgLn
)
347 IF NoDebug
OR (UCASE
$(StrucData$(3)) = "IGNORE") THEN
350 PRINT #
2, " {I_" + StrucData
$(1) + ", " + StrucData
$(5) + ", {" + StrucData
$(2) + "}, " + qt$
+ StrucData
$(3) + qt$
+ ", " + StrucData
$(4) + "},"
353 PRINT #
2, " {-1}" + crlf$
+ "};" + crlf$
356 OpCodeBegS$
= "static struct itemplate *itable_"
357 OpCodeBegE$
= "[] = {"
358 OpCodeEnd$
= " NULL" + crlf$
+ "};" + crlf$
361 PRINT #
2, OpCodeBegS$
+ RIGHT
$("00" + HEX
$(a), 2) + OpCodeBegE$
363 FOR b
= 1 TO LEN(h
$) STEP
2
364 OpCodePos
= CVI(MID$(h$, b
, 2))
365 PRINT #
2, " instrux +" + STR
$(OpCodePos) + ","
370 PRINT #
2, "struct itemplate **itable[] = {"
372 PRINT #
2, " itable_" + RIGHT
$("00" + HEX
$(a), 2) + ","
385 FUNCTION ReplaceOp$
(a
$)
393 ReplaceOp$
= "IMMEDIATE"
395 ReplaceOp$
= "MEMORY"
396 CASE "MEM8", "MEM16", "MEM32", "MEM64", "MEM80"
397 ReplaceOp$
= "MEMORY|BITS" + MID$(tst$, 4)
398 CASE "REG8", "REG16", "REG32"
400 CASE "RM8", "RM16", "RM32"
401 ReplaceOp$
= "REGMEM|BITS" + MID$(tst$, 3)
402 CASE "IMM8", "IMM16", "IMM32"
403 ReplaceOp$
= "IMMEDIATE|BITS" + MID$(tst$, 4)
409 FUNCTION Min
% (a
%, b
%)
410 IF a
% < b
% THEN Min
% = a
% ELSE Min
% = b
%
413 FUNCTION StrAscii (a
$)
421 ' same as =INSTR(SearchStart, SearchIn, ANY SearchFor$) in PowerBASIC(tm)
423 FUNCTION StrInstrLeft (SearchStart
, SearchIn
$, SearchFor
$)
424 ValuesCount
= LEN(SearchFor
$)
425 MaxValue
= LEN(SearchIn
$) + 1
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
)
432 IF MinValue
= MaxValue
THEN MinValue
= 0
433 StrInstrLeft
= MinValue
437 ' This is a very damn fuckin' shit version of this splitting routine.
438 ' At this time, it's not very useful :]
440 SUB StrSplitString (SplitString
$, SplitChars
$, SplitField
$(), SplitCount
)
441 StartIndex
= LBOUND(SplitField
$)
442 LastIndex
= UBOUND(SplitField
$)
443 ActualIndex
& = StartIndex
447 FoundPos
= StrInstrLeft(LastPos
, SplitString
$, SplitChars$
+ CHR
$(34))
451 DO WHILE FoundPos
> 0
452 FoundCharVal
= StrAscii(MID$(SplitString$, FoundPos
, 1))
453 PosDiff
= (FoundPos
- LastPos
) + 1
454 SELECT CASE FoundCharVal
456 TempString$
= TempString$
+ MID$(SplitString$, LastPos
, PosDiff
- 1)
464 TempString$
= TempString$
+ MID$(SplitString$, LastPos
, PosDiff
- 1)
465 SplitField
$(ActualIndex&) = TempString$
467 ActualIndex
& = ActualIndex
& + 1
468 IF ActualIndex
& > LastIndex
THEN
469 ActualIndex
& = LastIndex
476 LastPos
= FoundPos
+ 1
477 FoundPos
= StrInstrLeft(LastPos
, SplitString
$, SplitChars
$)
478 LOOP WHILE LastPos
= FoundPos
479 FoundPos
= StrInstrLeft(LastPos
, SplitString
$, SplitChars$
+ CHR
$(34))
482 LastPos
= LEN(SplitString
$) + 1
485 LastPos
= FoundPos
+ 1
486 FoundPos
= StrInstrLeft(LastPos
, SplitString
$, CHR
$(34))
488 SplitString$
= SplitString$
+ CHR
$(34)
489 FoundPos
= LEN(SplitString
$)
494 IF LEN(TempString
$) > 0 THEN
495 SplitField
$(ActualIndex&) = TempString$
496 ELSEIF LastPos
<= LEN(SplitString
$) THEN
497 SplitField
$(ActualIndex&) = MID$(SplitString$, LastPos
)
499 ActualIndex
& = ActualIndex
& - 1
502 FOR a
= ActualIndex
& + 1 TO LastIndex
505 SplitCount
= (ActualIndex
& - StartIndex
) + 1
508 FUNCTION StrTrim$
(a
$, b
$)
509 StrTrim$
= StrTrimRight
$(StrTrimLeft$(a$, b
$), b
$)
512 FUNCTION StrTrimLeft$
(a
$, b
$) 'public
518 LOOP WHILE (p
< l
) AND (INSTR(b
$, t
$) > 0)
519 StrTrimLeft$
= MID$(a$, p
)
522 FUNCTION StrTrimRight$
(a
$, b
$) 'public
532 LOOP WHILE (p
> 0) AND (INSTR(b
$, t
$) > 0)
533 StrTrimRight$
= LEFT
$(a$, p
)