                               PSRINVAD 1.1

What started in 2016 as sloppy Sed scripts for five assemblers is now
a smorgasbord of other languages targeting (at minimum) 14 different
assemblers (with 100% identical instructions and size!).

Sed      : nasm a86 fasm wat wolf octasm tma tinyasm a72 nbasm
           jwasm lazy as86 djasm
AWK      : nasm a86 fasm wat wolf octasm tma tinyasm a72 nbasm
           as86 djasm
Pascal   : nasm a86 fasm wat wolf jwasm
Modula-2 : nasm a86 wat jwasm
Oberon   : nasm a86 fasm wat wolf octasm jwasm lazy
REXX     : nasm a86 fasm wat wolf jwasm
BASIC    : nasm a86 wat wolf
C        : nasm a86 wat wolf
assembly : a86
Perl     : (via NOMYSO) nasm
Ed       : fasm

(inc2tiny): AWK, REXX, Pascal, Modula-2, Oberon, BASIC, C

  wat lazy             =  need linker (tlink, wlink, warplink, val, djlink)

  a86 wolf octasm tma  =  no Win32- or Linux-hosted versions

  8086-friendly        =  Sed            (hhsed, sedmod, csed)
                       =  AWK            (MAWK or GK's OW build)
                       =  .BAS           (QBASIC)
                       =  .C             (SubC [2014] or IA16-ELF/GCC)
                       =  p2c .C output  (OpenWatcom 1.9 WCL)
                       =  TP55 or Alice  (or FPC v3 ppcross8086)
                       =  m2nasm.mod     (FST 4.0 or GPM '96)
                       =  obenasm.m      (Oberon-M 1.2)
                       =  fixinv.a86     (A86 4.05)

  8086-hosted          =  nasm, a86, wat (wasmr), jwasm (jwasmr),
                          wolf (wasm.com), tinyasm, a72, as86

Alice Pascal (TP 3 compatible) lacks:
  = units (but supports $I include)
  = {$ifdef}
  = exit (use goto)
  = longint (current kludge is incompatible)
  = "string" (must specify size, e.g. string[10])
  = inc() dec()
  = short circuit boolean evaluation (full, so beware dereferencing NIL!)
  = (APRUN.EXE cmdline) no paramcount, no paramstr()
  = (APRUN.EXE cmdline) must use named files, e.g. assign() before reset()

p2c will ignore all preprocessor directives, so anything between
{$ifdef} and {$endif} is compiled! It will crash on some things (set
constants), but overall anything reasonable will compile.  Default is
HP dialect, but you can tell it -LTURBO (and -a for ANSI C output).
There's also comments {language=vax} and {AnsiC=1} in .PAS you can use
to automate that.  DJGPP had a p2c port back in 1999. I guess that was
before GPC really took off.  Much better compatibility is found in
GPC, but it's more bloated, bigger output.

Since a lot of assemblers support symbolic equates (e.g. "B equ byte
ptr"), I was able, in one pass, to output to two files (.ASM and .INC)
which assemble simply and correctly without problems. This is my main
strategy: assume any instruction operand starting with ['A'..'Z'] and
being of length > length("DX") is a variable (indirect memory
reference) and needs to be surrounded by '[' and ']'.

Some assemblers don't support such symbolic equates properly, so I
have to do it the old-fashioned way in two passes. But I used AWK
(ASMDATA.AWK) to do it all in RAM, thus it saved me some effort.
However, Sed still needs two passes (scripts). Then I decided INC2TINY
would convert NASM (.ASM and .INC) into one .ASM for Tinyasm.  Still
two passes and not all in RAM, but at least it works (e.g. Alice).

But that still wasn't good enough. So, despite relative inexperience,
I went ahead to try to make an ISO 7185 compatible version doing it
all in RAM. Unfortunately, I only halfway succeeded. It works and
outputs "normalized" data. In other words, it's still compatible with
TASM and MASM (JWasm) and even A86, but it's in a format much easier
to fix later for additional assemblers. A very simple Diff makes
INVISO.PAS compatible with {$mode tp} and thus actual TP55.

Unfortunately, I tried to be *too* clever, so INVISO.PAS keeps the
whole source in RAM. I tried to tidy that (to some effect), but it's
still too much. So, despite not originally using the Heap at all (for
simplicity), I *must* use NEW/DISPOSE in TP55 because DGROUP constant
data must be less than 64 kb. (So it takes about 170 kb of RAM.) p2c
converts this to ANSI C just fine, but it needs /mc (Compact model)
for OpenWatcom because of larger than 64 kb Heap Data. (But that
source is too big and clunky and needs a rewrite.)

Okay, now I rewrote it yet again: ISONASM.PAS is basically INVNASM.PAS
but for {$classic-pascal}. (Further translated to Modula-2
[M2NASM.MOD] and Oberon [OBENASM.M].)

INV.REX, INVEP.PAS, INVTURBO.PAS, INVOBER.M, and INVMOD2.MOD also
normalize it in RAM to (still) work "out of the box" with TASM32,
JWasmR, WasmR, and A86.  Less than a minute's changes let it then
assemble with A72 (and similarly others):

  sed -e "/CODE_SEG/d" -e "/END/d" -e "s/DS:\[/[/" inv.asm >inv-a72.asm

  C:\>edlin inv.asm
   1,2d
   $d
   $d
   1,$rcs:[,[cs:
   1,$rDS:[,[
   1,$rES:[,[es:
   e inv-nasm.asm
  C:\>nasm16 -O3 -Dptr= -DOffset= -DOFFSET= inv-nasm.asm -o inv-nasm.com

So this is why I rewrote INVFNASM.PAS (and ignored INVOOPAS). It
didn't work in TP302, Alice, P5, or p2c. Even old INVA86.PAS choked!
Gotta keep it simple!

-- rugxulo _AT_ gmail

<EOF>
