ZXtool - intimately examine P files

Anything Sinclair ZX Basic related; history, development, tips - differences between BASIC on the ZX80 and ZX81
User avatar
XavSnap
Posts: 1941
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: ZXtool - intimately examine P files

Post by XavSnap »

Only a handful ZX81-chars does not exist in unicode.
:shock:
zscii.JPG
Vb81_XuR\Zx81_Fonts folder.
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: ZXtool - intimately examine P files

Post by bwinkel67 »

Fruitcake wrote: Thu Apr 30, 2020 1:47 pm Perhaps but there is no real necessity to escape it like there is with these other characters. After all, ** is supported directly instead of \*...
That one isn't a problem because in most code (i.e. non ZX81 BASIC) if it uses ** then it's accounted for...likely because it doesn't add context issues like " does...whereas if you use C/C++/Java/Perl/Python, you can't type a string like "Say ""hi"" to your neighbor" but instead have to do something like "Say \"hi\" to your neighbor" and thus the escape is a bit more natural since it's practiced elsewhere. I'd be fine with \"" actually instead of \" and, in fact, internally the ZXSimulator use \"" to keep things simple (since all other escape characters are length two) and when I read it in I look for \" and add a " and when I write it out I remove the extra ".
Fruitcake wrote: Thu Apr 30, 2020 1:47 pm zxtext2p uses # for a comment line which it simply ignores when converting the file:
Sorry, I should have given a better example. I have seen code like {128}{128}{128} and figured that the { and } are being used to allow ZX81 numeric code values to be used instead of character sequences such as \::\::\:: which I think represents the same thing.

Is anyone working on zxtool.exe anymore? Is there a source dump out there? Should be an easy fix to add in both and add a flag. There is precedence for having two ways since '\::' and '% ' are both supported.

I can also add the fix in but when the project is about size and time minimization since the point is to create an executable under 50K to run on an unexpanded QL that can run a full 16K ZX81 program, little changes like having to account for multiple conventions just adds to the bloat. Obviously if it were designed on a modern system, if you are at a tiny 2MB footprint then adding a few extra subroutines to be compatible with everything isn't such a big deal.

So for me it would be nice if zxtool.exe and zxtext2p.exe were compatible with each other. Are there other tools out there that replace these?
Fruitcake
Posts: 351
Joined: Wed Sep 01, 2010 10:53 pm

Re: ZXtool - intimately examine P files

Post by Fruitcake »

bwinkel67 wrote: Thu Apr 30, 2020 10:30 pm Sorry, I should have given a better example. I have seen code like {128}{128}{128} and figured that the { and } are being used to allow ZX81 numeric code values to be used instead of character sequences such as \::\::\:: which I think represents the same thing.
I haven't seen that used before.

bwinkel67 wrote: Thu Apr 30, 2020 10:30 pm Is anyone working on zxtool.exe anymore? Is there a source dump out there? Should be an easy fix to add in both and add a flag. There is precedence for having two ways since '\::' and '% ' are both supported.
The C source is available here:
http://freestuff.grok.co.uk/zxtext2p/index.html

Since it is still on v1.0 I assume it hasn't be updated in years and the copyright date in the readme says 2002.
bwinkel67 wrote: Thu Apr 30, 2020 10:30 pm little changes like having to account for multiple conventions just adds to the bloat
Ok, I see where you are coming from.

Another possible solution then is to have yet another utility that can convert things such as "" to \" and vice versa, i.e. can convert between all popular text formats. Yes a bit nasty but then at least you don't have to worry about trying to get other utilities changed...
User avatar
XavSnap
Posts: 1941
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: ZXtool - intimately examine P files

Post by XavSnap »

Another possible solution then is to have yet another utility
"Zxtoken" (win32) had been included in Vb81.
The \" and @C0 can be use.

Zxtext2p was changed by Chris Cowley, but i had to have a look to my backups.
>>> http://grok.co.uk/zxtext2p/index.html … [Thanks Fruitcake ! ]
( \" supported in this release !)

Win32 (DOS) binarys:
zxtext2p.zip
(36.33 KiB) Downloaded 259 times
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: ZXtool - intimately examine P files

Post by bwinkel67 »

Fruitcake wrote: Thu Apr 30, 2020 10:52 pm The C source is available here:
http://freestuff.grok.co.uk/zxtext2p/index.html
Oh, no I was asking for zxtool.exe source. Have been looking for it without success. Found this but I'm not sure if it is the same zxtool.exe since it's an entire library of tools and the specific is called zxtools.exe (note the s):

http://dskcenter.free.fr/zxtools.html

I've tried to just edit the binary to no avail. There are two spots with "" but they don't impact the output. I will see if I can disassemble it somehow (any recommendations for environments?). From the binary just some snippets:

Code: Select all

<assembly xmlns="urn:schemas\
-microsoft-com:asm.v1" manifestVersion="1.0">^M
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">^M
    <security>^M
      <requestedPrivileges>^M
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>^M
      </requestedPrivileges>^M
    </security>^M
  </trustInfo>^M
</assembly>
and

Code: Select all

 Complete Object Locator'^@^@^@ Class Hierarchy Descriptor'^@^@^@^@ Base Class Array'^@^@ Base Class Descriptor at (^@ Type Descriptor'^@^@^@`local static thread guard'^@`managed vector copy constructor iterator'^@^@`vector vbase copy constructor iterator'^@^@^@^@`vector copy constructor iterator'^@^@`dynamic atexit destructor for '^@^@^@^@`dynamic initializer for '^@^@`eh vector vbase copy constructor iterator'^@`eh vector copy constructor iterator'^@^@^@`managed vector destructor iterator'^@^@^@^@`managed vector constructor iterator'^@^@^@`placement delete[] closure'^@^@^@^@`placement delete closure'^@^@`omni callsig'^@^@ delete[]^@^@^@ new[]^@^@`local vftable constructor closure'^@`local vftable'^@`RTTI^@^@^@`EH^@`udt returning'^@`copy constructor closure'^@^@`eh vector vbase constructor iterator'^@^@`eh vector destructor iterator'^@`eh vector constructor iterator'^@^@^@^@`virtual displacement map'^@^@`vector vbase constructor iterator'^@`vector destructor iterator'^@^@^@^@`vector constructor iterator'^@^@^@`scalar deleting destructor'^@^@^@^@`default constructor closure'^@^@^@`vector deleting destructor'^@^@^@^@`vbase destructor'^@^@`string'^@^@^@^@`local static guard'^@^@^@^@`typeof'^@^@^@^@`vcall'^@`vbtable'^@^@^@`vftable'^@^@^@^=^@^@|=^@^@&=^@^@<<=^@>>=^@/=^@^@-=^@^@+=^@^@*=^@^@||^@^@&&^@^@|^@^@^@^^@^@^@~^@^@^@()^@^@%^@^@^@->*^@&^@^@^@--^@^@++^@^@->^@^@operator^@^@^@^@[]^@^@!=^@^@==^@^@!^@^@^@<<^@^@>>^@^@ delete^@ new^@^@^@^@__unaligned^@__restrict^@^@__ptr64^@__eabi^@^@__clrcall^@^@^@__fastcall^@^@__thiscall^@^@__stdcall^@^@^@__pascal^
So not sure what environment it was written in as I've not done much Windows programming. My aim would be to find out where it throws in two "" and just replace it with \" since then zxtext2p.exe and zxtool.exe will be compatible with each other and EightyOne won't care since it can handle both. I suppose you could argue (as has been done) to instead fix zxtext2p.exe but that doesn't help me since I'd rather like the zxtext2p.exe format and have conformed to it :-/
Last edited by bwinkel67 on Fri May 01, 2020 12:54 am, edited 2 times in total.
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: ZXtool - intimately examine P files

Post by bwinkel67 »

XavSnap wrote: Fri May 01, 2020 12:16 am Win32 (DOS) binarys:
zxtext2p.zip
Wow, this version is 36K in size. I have another, older one that is 120K in size and both seem to do the same thing. I guess it was compiled in a better environment for Windows?
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: ZXtool - intimately examine P files

Post by bwinkel67 »

Fruitcake wrote: Thu Apr 30, 2020 10:52 pm
bwinkel67 wrote: Thu Apr 30, 2020 10:30 pm Sorry, I should have given a better example. I have seen code like {128}{128}{128} and figured that the { and } are being used to allow ZX81 numeric code values to be used instead of character sequences such as \::\::\:: which I think represents the same thing.
I haven't seen that used before.
If you look at this you'll see that the HTML listings use that mechanism. How that was converted I haven't looked into yet.

https://www.reids4fun.com/zx81/star-fig ... _list.html
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: ZXtool - intimately examine P files

Post by bwinkel67 »

bwinkel67 wrote: Fri May 01, 2020 1:09 am [ How that was converted I haven't looked into yet.
I found it...the author wrote a simple Perl program to do the conversion from .p to txt.

Code: Select all

#!f:/opt/perl/bin/perl

########################################################################
#
# program  :  zl
# version  :  @(#)bin zl v1.1 11/15/98
# author   :  Steven Reid (slreid@micron.net)
# purpose  :  To convert ZX81 programs (P files) to HTML
#             (by default) or text (using the "text' option).
#             Currently, zl sends to standard out.
# note     :  You'll probably need to change the first line to
#             the location of your perl executable.
# usage    :  zl {ZX81 Program} [text]
#               or
#             zl {ZX81 Program} [text] > {filename}
#             
#########################################################################

# initialize environment
$|++; # unbuffer output
use strict;

# load packages

# define constants
my @ZX81_CHAR_TABLE = (
  ' ','{1}','{2}','{7}','{4}',
  '{5}','{T}','{E}','{A}','{D}',
  '{S}','"','#','$',':',
  '?','(',')','>','<',
  '=','+','-','*','/',
  ';',',','.','0','1',
  '2','3','4','5','6',
  '7','8','9','A','B',
  'C','D','E','F','G',
  'H','I','J','K','L',
  'M','N','O','P','Q',
  'R','S','T','U','V',
  'W','X','Y','Z','RND',
  'INKEY$','PI','CALL ','ERR MSGS ','DPOKE ',
  'ERROR ','CHAR ',' ','TRACE ','DRAW ',
  'UNDRAW ','PROTECT ','EDIT ','AUTO ','DEF PROC ',
  'END PROC ','','DELETE ','DO ','LOOP ',
  'EXIT ','UNTIL ','WHILE ','WHEN ','INDENT ',
  'RESEQ ','OFF','CURSOR ','DATA ','RESTORE ',
  'READ ','NOSTALGIC ','USER ','*','ON',
  'HOME ','BREAK ','DPEEK ','LINE ','POP ',
  'PUSH ','CLR STACK ','DUP ','ELSE ','END WHEN ',
  '?','?','?','?','?',
  '?','?','?','?','?',
  '?','?','?','?','?',
  '?','?','?','[ ]','{Q}',
  '{W}','{6}','{R}','{8}','{Y}',
  '{E}','{H}','{G}','{F}','["]',
  '[#]','[$]','[:]','[?]','[(]',
  '[)]','[>]','[<]','[=]','[+]',
  '[-]','[*]','[/]','[;]','[,]',
  '[.]','[0]','[1]','[2]','[3]',
  '[4]','[5]','[6]','[7]','[8]',
  '[9]','[A]','[B]','[C]','[D]',
  '[E]','[F]','[G]','[H]','[I]',
  '[J]','[K]','[L]','[M]','[N]',
  '[O]','[P]','[Q]','[R]','[S]',
  '[T]','[U]','[V]','[W]','[X]',
  '[Y]','[Z]','""','AT ','TAB ',
  '?','CODE ','VAL ','LEN ','SIN ',
  'COS ','TAN ','ASN ','ACS ','ATN ',
  'LN ','EXP ','INT ','SQR ','SGN ',
  'ABS ','PEEK ','USR ','STR$ ','CHR$ ',
  'NOT ','**',' OR ',' AND ','<=',
  '>=','<>',' THEN ',' TO ',' STEP ',
  'LPRINT ','LLIST ','STOP ','SLOW ','FAST ',
  'NEW ','SCROLL ','CONT ','DIM ','REM ',
  'FOR ','GOTO ','GOSUB ','INPUT ','LOAD ',
  'LIST ','LET ','PAUSE ','NEXT ','POKE ',
  'PRINT ','PLOT ','RUN ','SAVE ','RAND ',
  'IF ','CLS ','UNPLOT ','CLEAR ','RETURN ',
  'COPY '
);
my $SYSTEM_VARS_START = 16393;
my $PROGRAM_START     = 16509;
my @KEYBOARD = (246, 252, 234, 247, 249, 254, 250, 238, 244, 245, 255, 253, 232, 251, 231, 243,
  242, 230, 248, 233, 235, 236, 237, 239, 240, 241);
my @SHIFT = (117, 218, 222, 223, 192, 217, 224, 219, 221, 220, 227, 225, 228, 229, 226, 216);
my @FUNCTION = (199, 200, 201, 207, 64, 213, 214, 196, 211, 194, 202, 203, 209, 210, 208, 197,
  198, 212, 205, 206, 193, 65, 215, 66);

# define variables
use subs qw(peek newline getchar);
my $in = shift || die "input file required!\n";
my $html = (shift || '') eq 'text' ? 0 : 1;
my $ptr = $PROGRAM_START;	# ZX81 memory pointer
my $cnt = 0;			# line pointer
my $len = 0;			# length of line
my $p   = '';			# program file
my $c   = '';			# char value
my $z   = '';			# temp space

# main loop

# set up character set
if ($html) {
  for (@KEYBOARD, @SHIFT, @FUNCTION) {
    $ZX81_CHAR_TABLE[$_] = "<B>$ZX81_CHAR_TABLE[$_]</B>";
  }
  $ZX81_CHAR_TABLE[0]   = '&nbsp;';			# ' ';
  $ZX81_CHAR_TABLE[11]  = '&quot;';			# '"';
  $ZX81_CHAR_TABLE[12]  = '&#163;';			# '£';
  $ZX81_CHAR_TABLE[18]  = '&gt;';			# '<';
  $ZX81_CHAR_TABLE[19]  = '&lt;';			# '>';
  $ZX81_CHAR_TABLE[128] = '[&nbsp;]';			# '[ ]';
  $ZX81_CHAR_TABLE[139] = '&quot;';			# '["]';
  $ZX81_CHAR_TABLE[140] = '[&#163;]';			# '[£]';
  $ZX81_CHAR_TABLE[146] = '[&gt;]';			# '[<]';
  $ZX81_CHAR_TABLE[147] = '[&lt;]';			# '[>]';
  $ZX81_CHAR_TABLE[219] = '<B>&lt;=</B>';		# '<=';
  $ZX81_CHAR_TABLE[220] = '<B>&gt;=</B>';		# '>=';
  $ZX81_CHAR_TABLE[221] = '<B>&lt;&gt;</B>';		# '<>';
  $ZX81_CHAR_TABLE[192] = '<B>&quot;&quot;</B>';	# '""';
}

# open the ZX81 program file
open P, $in or die "can't open file: $in ($!)\n";
binmode P;  # required for DOS, UNIX ignores this

if ($html) {
  print "<HTML>\n<HEAD>\n<TITLE>ZX81 Program: \U$in</TITLE>\n</HEAD>\n",
    qq(<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n),
    qq(<H1>ZX81 Program: \U$in</H1><HR>\n\n);
} else {
  print "ZX81 Program: \U$in\n";
}

# get system variables
my $sys;
read P, $sys, $PROGRAM_START - $SYSTEM_VARS_START;

my $D_FILE = peek ($sys, 3);
my $VARS   = peek ($sys,  7);
my $E_LINE = peek ($sys, 11);
my $STKBOT = peek ($sys, 17);
my $STKEND = peek ($sys, 19);
if ($html) {
  print <<HTML;
<P><B>SYSTEM VARIABLES</B><P><TT>
PROG&nbsp;&nbsp;: $PROGRAM_START<BR>
D-FILE: $D_FILE<BR>
VARS&nbsp;&nbsp;: $VARS<BR>
E-LINE: $E_LINE<BR>
STKBOT: $STKBOT<BR>
STKEND: $STKEND<BR>
</TT></P><HR><P>
<B>LEGEND</B><P>
<TT>[A]</TT> means INVERSE A<BR>
<TT>{A}</TT> means GRAPHICS A<BR>
<TT><B>PRINT </B></TT> means treat as KEYWORD P<BR>
</P><HR><P>
<B>PROGRAM LISTING</B><BR><TT>
HTML
} else {
  print "\n----- SYSTEM VARIABLES -----\n\n";
  printf "PROG  : %5d\n", $PROGRAM_START;
  printf "D_FILE: %5d\n", $D_FILE;
  printf "VARS  : %5d\n", $VARS;
  printf "E_LINE: %5d\n", $E_LINE;
  printf "STKBOT: %5d\n", $STKBOT;
  printf "STKEND: %5d\n", $STKEND;
  print "\n----- LEGEND -----\n\n";
  print "[A] means  INVERSE A\n";
  print "{A} means GRAPHICS A\n";
  print "# is subsituted for the British pound sign.\n" if $ZX81_CHAR_TABLE[12] eq '#';
  print "\n----- START OF LISTING -----\n";
}

# convert file to text
newline;
while ( $ptr < $D_FILE ) {
  $c = getchar; $ptr++;
  if ($c == 118) {		# end of line
    newline;
  } elsif ( $c == 126 ) {	# hidden number
    read P, $z, 5; $ptr+=5; # $cnt+=5;
  } else {			# print value
    print $ZX81_CHAR_TABLE[$c];
  }
}


if ($html) { print "</TT></P><HR>\n</BODY>\n</HTML>" }
else       { print "\n\n----- END OF LISTING -----\n" }

close P;
# end main
########################################################################
sub peek {
  my ($str, $pos) = @_;
  my $x = unpack 'C', substr $str, $pos,   1;
  my $y = unpack 'C', substr $str, $pos+1, 1;
  return ( $x + 256 * $y );
}
########################################################################
sub newline {
  if ( $ptr >= $D_FILE ) { return }
  my $line = 256 * (getchar) + (getchar);
  read P, $z, 2;
  print qq(<BR><FONT COLOR="#0000FF">) if $html;
  $p = sprintf "\n%4d ", $line; $p =~ s/ /\&nbsp;/gs if $html; print $p;
  print qq(</FONT>) if $html;
  $ptr += 4;
}
########################################################################
sub getchar { return unpack 'C', getc P }
########################################################################
I guess I never gave it much thought but it seems a .p file is literally just a translation of characters, graphics, and keywords to the ZX81 code set. There is no sort of header information embedded in it, correct? If that's all it is then writing a zxPconvert.exe utility that goes both way ought to be simple...or maybe just a zxp2text.exe to bookend the already existing zxtext2p.exe. I might just do the latter if I can't find the zxtool.exe source. A simple command line utility that is the C version of the Perl above but uses the zxtext2p.exe syntax ought to be a simple task.
Last edited by bwinkel67 on Fri May 01, 2020 1:37 am, edited 2 times in total.
User avatar
XavSnap
Posts: 1941
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: ZXtool - intimately examine P files

Post by XavSnap »

Wow, this version is 36K in size. I have another, older one that is 120K in size and both seem to do the same thing. I guess it was compiled in a better environment for Windows?
Mine was compiled on W7/GCC/WinDev with optimisations.
May be several icons enclosed in the binary.
;)

http://dskcenter.free.fr/zxtools.html
"ZxBasicEditor" is only a front-end in Visual Basic, to compile 'P' files using the command line ZxText2P...
"ZxToken" is the compiler enclosed in Vb81.
Last edited by XavSnap on Fri May 01, 2020 1:27 am, edited 2 times in total.
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
Fruitcake
Posts: 351
Joined: Wed Sep 01, 2010 10:53 pm

Re: ZXtool - intimately examine P files

Post by Fruitcake »

bwinkel67 wrote: Fri May 01, 2020 1:16 am I found it...the author wrote a simple Perl program to do the conversion from .p to txt.
A variety of formats to choose between! :lol:

bwinkel67 wrote: Fri May 01, 2020 1:16 am I guess I never gave it much thought but it seems a .p file is litterally just a translation of kewyrods to the ZX81 code set.
Plus system variables, BASIC variables and display file...

bwinkel67 wrote: Fri May 01, 2020 1:16 am or maybe just a zxp2text.exe to bookend the already existing zxtext2p.exe.
I see there is a P2TXT utility here:
http://www.retroisle.com/sinclair/zx81/software.php

But I've never used it or know what format it outputs non-ASCII characters in... Maybe yet another format...
Post Reply