New tool for Z80 cross developers! (Win)

بواسطة NYYRIKKI

Enlighted (6016)

صورة NYYRIKKI

23-01-2011, 22:03

Important news for Windows cross developers:

Have you ever made an assembler program and ended up having lots of labels like "FOO", "FISH"
"WTF", "SOMETHING" etc.? Have you sometimes disassembled a routine and then made some changes
so that your source is still full of "XC81C" type of labels? Does your source look like crap:
Capital and non capital letters are mixed, indent changes every now and then, comments are
not where they should be and you end up going up and down your source all the time? Now you
would like to release your source as freeware, but you don't dare because it all looks so bad...

If any of this sounded familiar, then here is solution to your troubles that fixes all of this
without hours of meaningless work!

Let me present:

 -----------------------------------------
 
 FixAsm(.vbs) 1.0 Made By: NYYRIKKI (2011)

 Usage:
 CSCRIPT //NOLOGO FixAsm.vbs <INPUTFILE.ASM> <OUTPUTFILE.ASM> [<LABELFILE.TXT>]
 [/C:{asm indent}[,{parameter indent}[,{comment indent}]]] [/R] [/L] [/U]


 <INPUTFILE.ASM>    is ASCII file containing your original source

 <OUTPUTFILE.ASM>   is ASCII file that will be written by this program.
                    (Use "CON" if you only want to display results.)

 {asm indent}       This is the column where assembler commands should be put to.

 {parameter indent} This is the column where assembler command parameters should be put to. Use
                    value "0" if you want assembler commands and parameters separated with space.

 {comment indent}   When there is comment in same line with assembler command, this will select the
                    indent for that case. Comments that start from beginning of line will still stay
                    without change and comments that are alone or with label will be adjusted to
                    same indent as commands.
                    
 /R                 This will remove all comments (except the ones created by <LABELFILE.TXT>)
                    If line does not contain anything else, but comment the whole line is deleted.
 /L                 This will change the source to lowercase letters
 /U                 This will change the source to uppercase letters
                    Changeing case will not affect string variables or comments.
                    
 <LABELFILE.TXT>    is TAB-delimitted ASCII file that contains rules, how to change labels.
 
                    Labelfile format is easy: <OLDLABEL>[{TAB}[<NEWLABEL>][{TAB}[<COMMENT>]]]{CRLF}
                    The number of lines is limited to 5000

<OLDLABEL>          Is the label that you currently have in your program this is in format:
                    <LABEL>[.<CHILD LABEL>]

<NEWLABEL>          This is the label name in output file

<COMMENT>           This comment is added to each line where this label is found exept to line
                    that defines this label.

You can use following script to exract template labels from .SYM file:

' This program extracts label names from .SYM file. (Tested with sjasm 0.42b8)
'
' CSCRIPT //NOLOGO Extract_labels.vbs <INPUTFILE.SYM> <OUTPUTFILE.TXT>
'
if wscript.arguments.count=2 then
 Set fso = CreateObject("Scripting.FileSystemObject")
 filename=wscript.arguments.item(0)
 if fso.FileExists (filename) then
  Set file = fso.OpenTextFile(filename, 1, False, tristatefalse)
  set wfile= fso.OpenTextFile(wscript.arguments.item(1), 2, True, tristatefalse)
  Do While Not File.AtEndOfStream
   a = File.readline
   b = split(a,":")
   wfile.writeline B(0)
  Loop
  File.Close
  wfile.Close
 else
  wscript.echo "File not found"
 end if
else
 wscript.echo "Invalid number of parameters"
end if


Tip: You can open this generated file in Excel and edit it there.
     (Put new labels to column B and comments in column C)
     Remember to save as .TXT (Tab delimitted)
     

Below is the actual program. Copy / Paste it and save as "FixAsm.vbs"

' FixAsm(.vbs) 1.0 Made By: NYYRIKKI (2011)
' This program is meant to fix outlook of Z80-assembler files
'
' Usage:
' CSCRIPT //NOLOGO FixAsm.vbs <INPUTFILE.ASM> <OUTPUTFILE.ASM> [<LABELFILE.TXT>]
' [/C:{asm indent}[,{parameter indent}[,{comment indent}]]] [/R] [/L] [/U]

DIM filename(2)
DIM lab(5000,3)
DIM col(2)

fn=0
lower=false
upper=false
nocoms=false
colfx=false

for I=0 to wscript.arguments.count-1
 select case left(ucase(wscript.arguments.item(i)),2)
  case "/U"
   upper=true
  case "/L"
   lower=true
  case "/C"
   colfx=true
   col2=split(mid(wscript.arguments.item(i),4)+",0,0,0",",")
   for w=0 to 2
    col(w)=int(col2(w))
   next
  case "/R"
   nocoms=true
  case else
   filename(fn)=wscript.arguments.item(i)
   fn=fn+1
 end select
next

if fn<2 or fn>3 then
 wscript.echo "Invalid number of parameters"
else
 Set fso = CreateObject("Scripting.FileSystemObject")
 if fso.FileExists (filename(0)) then
  if fso.FileExists (filename(2)) then
   Set lfile = fso.OpenTextFile(filename(2), 1, False, tristatefalse)
   max=0
   Do While Not lfile.AtEndOfStream
    a = lfile.readline
    b = split(a+chr(9)+chr(9),chr(9))
    lab(max,0)=b(0)
    lab(max,1)=b(1)
    lab(max,2)=chr(7)+chr(max and 255)+chr(max\256)
    lab(max,3)=b(2)
    if b(1)="" then lab(max,1)=b(0)
    if b(0)<>"" and (b(0)<>lab(max,1) or b(2)<>"") then max=max+1
   Loop
   lfile.Close
   if max<1 then
    wscript.echo "No labels to replace!"
    wscript.quit -1
   end if

   wscript.echo "Labels to edit:" & max
   max=max-1

   ' Check that requests are valid

   for k=0 to 1
    for y=0 to max-1
     for i=y+1 to max
      if lab(y,k)=lab(i,k) then
       wscript.echo "Duplicate label: " & lab(y,k)
       wscript.quit -1
      end if
     next
    next
   next

  end if
 else
  wscript.echo "File not found!"
  wscript.quit -1
 end if

 labchr="0123456789_"
 for i= ASC("A") to ASC("Z")
  labchr=labchr+chr(i)+chr(i+32)
 next

 Set rfile = fso.OpenTextFile(filename(0), 1, False, tristatefalse)
 set wfile = fso.OpenTextFile(filename(1), 2, True, tristatefalse)
 Do While Not rfile.AtEndOfStream
  outpt=true
  a = rfile.readline
  if nocoms=true and len(a)>0 then
   a=commentremove(a)
   if len(a)=0 then outpt=false
  end if
  if colfx=true then a = colfix(a)
  a = tailrem(a)
  if filename(2)<>"" then
   b = getname(a)
   if b<>"" then
    if left(b,1)<>"." then parent=b
   end if
   for i=0 to max
    a=sreplace(a,lab(i,0),lab(i,2),lab(i,3))
   next
   for i=0 to max
    a=sreplace(a,lab(i,2),lab(i,1),"")
   next
  end if
  if colfx=true and col(2)>0 then a = colfix2(a)
  if upper=true or lower=true then a=ccase(a)
  if outpt=true then wfile.writeline a
 Loop
 rFile.Close
 wfile.Close

end if

function sreplace(s,olab,nlab,comment)
 olab2=olab
 nlab2=nlab
 sreplace=s

 ' Check if child
 if instr(olab2,".")>0 then
  if left(olab2,1)=chr(7) and mid(olab2,4,1)="." then
   if parent<>left(olab,4) then exit function
   olab2=mid(olab2,4)
  else
   if parent<>left(olab,instr(olab2,".")-1) then exit function
   olab2=mid(olab2,instr(olab2,"."))
  end if
 end if
 if instr(nlab2,".")>1 then
  if left(nlab2,1)=chr(7) and mid(nlab2,4,1)="." then
   nlab2=mid(nlab2,4)
  else
   nlab2=mid(nlab2,instr(nlab2,"."))
  end if
 end if

 pos=0
 do
  pos=instr(pos+1,sreplace,olab2)
  if pos=0 then exit function
  if pos=1 then
   sreplace=label(sreplace,olab2,nlab2)
  else
   sreplace=ulabel(sreplace,olab2,nlab2,pos,comment)
  end if
 loop
end function

function label(s,olab3,nlab3)
 if instr(chr(9)+" :",mid(s+" ",len(olab3)+1,1))=0 then exit function ' Part of other label

 ei=mid(s,len(olab3)+1)
 eo=space(len(olab3))

 do until len(ei)=0 or instr(chr(9)+" :",mid(ei,1,1))=0
  ch=left(ei,1)
  if ch<>chr(9) then ch=" "
  eo=eo+ch
  ei=mid(ei,2) 
 loop
 if len(ei)=0 then
  label=nlab3+":"
 else
  if len(nlab3)+2>len(eo) then
   label=nlab3+":"+chr(13)+chr(10)+eo+ei
  else
   label=nlab3+":"+mid(eo+ei,len(nlab3)+2)
  end if
 end if
end function

function ulabel(s,olab4,nlab4,pos,comment)
 ulabel=s
 if instr(labchr,mid(s+" ",pos+len(olab4),1))>0 then exit function
 if instr(labchr,mid(s,pos-1,1))>0 and left(olab4,1)<>"." then exit function
 ulabel=left(s,pos-1)+nlab4+mid(s,pos+len(olab4))
 if comment="" then exit function
 ulabel=commentremove(ulabel)+" ; "+comment
end function

function getname(s)
 getname=""
 for ns=1 to len(s)
  if instr(chr(9)+" :;",mid(s,ns,1))>0 then exit function
  getname=getname+mid(s,ns,1)
 next
end function

function commentremove(t)
 commentremove=t
 pos=1
 do
  if len(t)=0 then exit function
  h5=instr(pos,t,";")
  if h5=0 then exit function
  h1=instr(pos,t,chr(34))
  h2=instr(pos,t,chr(39))

  if h2>2 then
   if ucase(mid(t,h2-2,3))="AF'" then h2=instr(h2+1,t,chr(39))  ' EX AF,AF'
  end if
  if h1=0 and h2=0 then
   commentremove=tailrem(left(t,instr(pos,t,";")-1))
   exit function
  else
   if h1=0 then h1=len(t)
   if h2=0 then h2=len(t)
   if h1>h2 then
    h3=h2
    h2=h1
    h1=h3
    h4=chr(39)
   else
    h4=chr(34)
   end if
   if h5

0 and len(tailrem)>0 tailrem=left(tailrem,len(tailrem)-1) loop end function function ccase(t) ccase=t pos=1 'vpos=1 do if len(t)=0 then exit function h5=instr(pos,t,";") 'if h5=0 then exit function h1=instr(pos,t,chr(34)) h2=instr(pos,t,chr(39)) if h2>2 then if ucase(mid(t,h2-2,3))="AF'" then h2=instr(h2+1,t,chr(39)) ' EX AF,AF' end if if h5=0 and h1=0 and h2=0 then ccase=left(ccase,pos-1)+ulcase(mid(ccase,pos)) exit function else if h1=0 then h1=len(t) if h2=0 then h2=len(t) if h5=0 then h5=len(t) if h1>h2 then h3=h2 h2=h1 h1=h3 h4=chr(39) else h4=chr(34) end if if h5

len(b) then cem=space(col(0)-len(b)-1) else cmpos=len(b) end if dat=emptyrem(mid(txt,len(b)+1)) colfix=b+":"+cem+dat if left(dat,1)=";" then exit function end if do cmpos=cmpos+1 loop while cmpos<>len(colfix) and instr(chr(9)+" :",mid(colfix,cmpos,1))=0 if cmpos<>len(colfix) and col(1)-cmpos>0 then colfix=mid(colfix,1,cmpos-1)+space(col(1)-cmpos+1)+ emptyrem(mid(colfix,cmpos)) end if end function function emptyrem(t) emptyrem=t do while len(emptyrem)>0 and instr(chr(9)+" :",mid(emptyrem,1,1))>0 emptyrem=mid(emptyrem,2) loop end function function colfix2(txt) colfix2=txt if len(txt)>col(0)+1 then if mid(txt,col(0)+1,1)=";" then exit function ' Leave comment to command space end if alku=commentremove(txt) ln=emptyrem(alku) if len(ln)=0 then exit function if len(alku)=len(txt) then exit function cem=" " alk=instr(alku,chr(10)) if col(2)-len(alku)+alk>0 then cem=space(col(2)-len(alku)+alk) colfix2=alku+cem+emptyrem(mid(txt,len(alku)+1)) end function

... as you may see VBscript is not my strongest point, but it should be available in all modern
Windows computers. I think this program would need now something similar Tongue

(You can also use WSCRIPT, if you like windows more...)

About copyright:
Use can use, copy & change this program freely, you can embed to your web-page etc.
...but remember to mention me as original author! Tongue

Login أوregister لوضع تعليقاتك

بواسطة ro

Scribe (4902)

صورة ro

24-01-2011, 09:44

Great, will it blend?

بواسطة tcruise

Master (133)

صورة tcruise

24-01-2011, 14:25

Very good idea and a useful tool. How about I wip it up into C++ so it can be used on Windows and Linux environments? Will have a go tomorrow (when I get up), unless you have any objections in the mean time.

بواسطة NYYRIKKI

Enlighted (6016)

صورة NYYRIKKI

24-01-2011, 16:02

@ro: No, ro it will not blend... It will twirl, stretch, turn, expand and change, but as the source still produces 100% original binarys, I would say it does not blend. Tongue

@tcruise Go ahead! I would also like to use it as executable! Smile I think the only variables that needs to be global are PARENT and some of the flags. I was just too lazy to check out how to make those labels local in functions. You see, I'm not used to this stuff in MSX environment. Eek! I think it is easy to find also lots of other things that can be optimized. I just wanted to get out a working version...

I also must say that I really needed this as I always tend to make code first and think later. I'm also so lazy, that I tend to write something like "CHIFFE" instead of "Check_If_File_Exists"... Then I realize that I open it always when the file is found so I add that functionality as well. Then I realize that the name should be "Open_If_File_Exists", but instead it is called "CHIFFE"... That is ok as long as I keep working on the source, but is pain in the ass if I try to realize what this program does after some months... Smile2