Processor Tech ENT file utility - CP/M

This is a discussion on Processor Tech ENT file utility - CP/M ; I have written a utility that allows Processor Technology ".ent" files to be loaded and run from CP/M. ".ent" files are ASCII representations of memory contents that are usually loaded from casette tape and processed by one of the Processor ...

+ Reply to Thread
Results 1 to 19 of 19

Thread: Processor Tech ENT file utility

  1. Processor Tech ENT file utility

    I have written a utility that allows Processor
    Technology ".ent" files to be loaded and run
    from CP/M. ".ent" files are ASCII representations
    of memory contents that are usually loaded from
    casette tape and processed by one of the Processor
    Tech ROM monitor programs. If you have a Sol or
    an S-100 box with PT cards and are running CP/M,
    this may be of use to you.

    Source code and other details can be found here:
    http://wsudbrink.dyndns.org:8080/

  2. Re: Processor Tech ENT file utility

    Bill Sudbrink wrote:
    > I have written a utility that allows Processor
    > Technology ".ent" files to be loaded and run
    > from CP/M.
    > Source code and other details can be found here:
    > http://wsudbrink.dyndns.org:8080/


    Looks like a nice program, reasonably self-documented.

    Your Web page mentions Jim Battle's SOL Web page as a source
    for .ENT programs. Since your Web page appears to be be only
    to offer the program you wrote, why not offer your program to Jim?
    He can add it to his site (hopefully) and it will be more assessable.
    (I'd contact you directly with this sugestion but your page says in
    effect you'd rather work this way.)

    Herb Johnson

    Herbert R. Johnson, New Jersey USA
    web site
    domain mirror
    my email address: hjohnson AAT retrotechnology DOTT com
    if no reply, try in a few days: herbjohnson ATT comcast DOTT net
    "Herb's Stuff": old Mac, SGI, 8-inch floppy drives
    S-100 IMSAI Altair computers, docs, by "Dr. S-100"


  3. Re: Processor Tech ENT file utility


    In article <1151519510.562994.71340@p79g2000cwp.googlegroups.c om> "Herb Johnson" writes:
    >Bill Sudbrink wrote:
    >> I have written a utility that allows Processor
    >> Technology ".ent" files to be loaded and run
    >> from CP/M.
    >> Source code and other details can be found here:
    >> http://wsudbrink.dyndns.org:8080/

    >
    >Looks like a nice program, reasonably self-documented.


    Thanks!

    >Your Web page mentions Jim Battle's SOL Web page as a source
    >for .ENT programs. Since your Web page appears to be be only
    >to offer the program you wrote, why not offer your program to Jim?


    I emailed him directly, no reply yet. He may be on vacation or
    something.

    >(I'd contact you directly with this sugestion but your page says in
    >effect you'd rather work this way.)


    Well, I was really hoping to stimulate some discussion on CP/M
    programming. For instance, I'm not really happy with my
    relocation code. It's straight forward, but error prone as the
    programmer has to identify each address to be fixed up. I
    spent a little time trying to figure out how DDT does it but I
    couldn't find any source code for it and the disassembly is
    pretty hard to follow. I guess it was written in some HLL? Also,
    if you look in the comments, you will see that the working code
    at the top of the TPA makes no attempt to keep from stomping on
    itself. I couldn't work out an "elegant" way to check this.

    Bill




  4. Re: Processor Tech ENT file utility

    Bill Sudbrink wrote:

    > Well, I was really hoping to stimulate some discussion on CP/M
    > programming. For instance, I'm not really happy with my
    > relocation code. It's straight forward, but error prone as the
    > programmer has to identify each address to be fixed up. I
    > spent a little time trying to figure out how DDT does it but I
    > couldn't find any source code for it and the disassembly is
    > pretty hard to follow. I guess it was written in some HLL? Also,
    > if you look in the comments, you will see that the working code
    > at the top of the TPA makes no attempt to keep from stomping on
    > itself. I couldn't work out an "elegant" way to check this.
    >
    > Bill


    I only took a few tens of minutes to look at the code you wrote. It's
    at least reasonably readable, that's good. I'd suggest you put a date
    stamp in for each fix you do, so users can keep track of the "current"
    version. A simple scheme is to comment with latest date and fix, and
    then your welcome message includes the latest date.

    It's ambitious to do a "real time" move of code AND to execute it in
    place (or almost so, you offset it temporarily to avoid page zero).
    It's less ambitious to open a file, perform some relocation tricks, and
    write the results to another file for loading later. So you should
    expect some challenges with the first method.

    If it's difficult to both MOVE the code and to CHECK the code, then
    write another program! Do the checks seperately in another program, or
    do it in a earlier pass in your current program. It's an old trick, to
    do multiple passes to save space or to reuse space, versus doing
    everything in one pass. And it's a trick you already use. A seperate
    pass could tell you if 1) the .ENT file is in the correct format and 2)
    If the files will load above the TPA. Then your relocated code need
    only convert and store with less error checking, a shorter relocated
    program even if the total program is longer.

    Your post asks how to better relocate a part of your program code. You
    mention how CP/M did it as a possible method. I believe the way CP/M
    produced relocation was through a seperate process of assembling code
    twice, at different ORG's, and then testing the binaries for
    differences, to create a table of offset addresses. Then one binary
    file was "adjusted" based on that table to be relocated by SYSGEN. So
    SYSGEN only needed one binary, the table, and relocation code based on
    those. Something of that order, as I'll detail in a moment. DDT has to
    relocate itself; I guess it has that table buried in it somewhere. Your
    bit of code to relocate is small enough that you can hand-check for
    offsets, and tabularize them as you've done.

    I suppose for "efficiency" you can ORG your relocatable code to a
    "page" boundary (XX00H addresses), and relocate only to another page.
    So you only need to change the page address BYTE (upper byte of the
    address) and not BOTH bytes as you've done. That's also the scheme used
    in CP/M SYSGEN relocation, as I recall, from page to page. Since you
    know the relocation is always "up", by the same amount, you only have
    to add a fixed offset to the page address byte.

    Keep in mind a few tricks to reduce the apparent size of your program,
    if you think your program's size limits you. Beware: tricks can make it
    hard to debug, you may want to turn these features off and on. One
    trick is to overwrite data or code that is only used once. For instance
    you can use your "welcome" message as data space for code LATER in your
    program.

    You have one routine that you code TWICE, a move block routine - I'm
    not sure why you can't use the relocatable version before it's moved.
    Maybe you thought you could not use the non-relocated version AFTER
    your move!

    You wanted discussion; here it is. Hope I got it correct.

    Herb Johnson

    erbert R. Johnson, New Jersey USA
    web site
    domain mirror
    my email address: hjohnson AAT retrotechnology DOTT com
    if no reply, try in a few days: herbjohnson ATT comcast DOTT net
    "Herb's Stuff": old Mac, SGI, 8-inch floppy drives
    S-100 IMSAI Altair computers, docs, by "Dr. S-100"


  5. Re: Processor Tech ENT file utility


    "Bill Sudbrink" wrote:

    > Well, I was really hoping to stimulate some discussion on CP/M
    > programming. For instance, I'm not really happy with my
    > relocation code. It's straight forward, but error prone as the
    > programmer has to identify each address to be fixed up. I
    > spent a little time trying to figure out how DDT does it but I
    > couldn't find any source code for it and the disassembly is
    > pretty hard to follow. I guess it was written in some HLL? Also,
    > if you look in the comments, you will see that the working code
    > at the top of the TPA makes no attempt to keep from stomping on
    > itself. I couldn't work out an "elegant" way to check this.


    First, congratulations for your program. For years, I have published small
    useful utilities for CP/M.

    Unfortunately, I have been working very hard, physically, during the last few
    weeks, trying to get a job (I am doing a one month trial period), so I had not
    enough time and energy to dive into your program.

    You wrote: "I spent a little time trying to figure out how DDT does it". Well,
    for me it is obvious. A few weeks or months ago, I asked yet-another-time for
    an article dealing, by the way, on relocation of BIOS subroutines "on the
    fly", and mentioned, at the time, that I knew 3 or 4 times to create PRL
    files. But maybe your program does not need to be a PRL file.

    Since you have difficulties understanding how DDT relocate itself, I will
    publish in the comp.os.cpm Newsgroup the article in which Gary Kildall
    explains how it is doing. Stay tuned. (Maybe I will be able to publish it
    tomorrow, else after-tomorrow afternoon.)

    I would have lots and lots of things to say about your program (the goal that
    it must do), but I am simply too tired: excuse me.

    Yours Sincerely,
    "French Luser"




  6. Re: Processor Tech ENT file utility

    French Luser wrote:

    > Since you have difficulties understanding how DDT relocate itself, I will
    > publish in the comp.os.cpm Newsgroup the article in which Gary Kildall
    > explains how it is doing. Stay tuned. (Maybe I will be able to publish it
    > tomorrow, else after-tomorrow afternoon.)


    I wrote several years ago a little utility to create relocatable code. There
    is not a big job, you make two assemblies with two different ORG (better if
    the difference is not a multiple of 256), compare byte by byte the two
    files, check that the differences are groups of two bytes and the
    difference is always the same (and corresponds to the difference of the
    ORG, if the program knows it). Fill a table with the addresses of the
    differences, or create a bitmap that marks it. Replace the positions marked
    for relocation with the value corresponding to an ORG 0 (or do the assembly
    of one of the files with this ORG) to simplify the relocation code.

    The relocation routine can be added to the code or loaded separately. In the
    first case, the relocation routine must be relocatable if you want to be
    able to load the program in an arbitrary position and execute it.

    The idea for that utility was taken by a reference to article of Kiddal that
    you mention, but without the article itself (I had no Internet access in
    that times).

    Unfortunately I don't have the code available, but maybe in a few weeks I
    will be able to read my old Amstrad CPC 3" diskettes and find it.

    PRL files can be created with RMAC and his linker. It's not difficult to
    write a relocation routine for this format.

    --
    Salu2

  7. Re: Processor Tech ENT file utility

    Julian Albo wrote:
    : I wrote several years ago a little utility to create relocatable code. There
    : is not a big job, you make two assemblies with two different ORG (better if
    : the difference is not a multiple of 256), compare byte by byte the two
    : files, check that the differences are groups of two bytes and the
    : difference is always the same (and corresponds to the difference of the
    : ORG, if the program knows it). Fill a table with the addresses of the
    : differences, or create a bitmap that marks it. Replace the positions marked
    : for relocation with the value corresponding to an ORG 0 (or do the assembly
    : of one of the files with this ORG) to simplify the relocation code.

    If you're constructing a PRL file, on the other hand, it's better if you
    do ORG them 256 bytes apart. Here's a program that generates a PRL from
    three files - one ORGed at 0, one ORGed at 1, and an optional one containing
    the loader. Something like:

    makeprl filename.0 filename.1 /dev/zero filename.prl

    Or with a loader:

    makeprl filename.0 filename,1 loader.bin filename.prl

    (loader.bin could, for example, be the PRL loader I posted at
    ).


    /*
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; Create a .PRL file from two binary files ;
    ; ;
    ; Copyright (C) 1998-1999, John Elliott ;
    ; ;
    ; This program is free software; you can redistribute it and/or modify ;
    ; it under the terms of the GNU General Public License as published by ;
    ; the Free Software Foundation; either version 2 of the License, or ;
    ; (at your option) any later version. ;
    ; ;
    ; This program is distributed in the hope that it will be useful, ;
    ; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
    ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
    ; GNU General Public License for more details. ;
    ; ;
    ; You should have received a copy of the GNU General Public License ;
    ; along with this program; if not, write to the Free Software ;
    ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ;
    ; ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
    */

    #include
    #include

    typedef unsigned char byte;

    /* Up to 3 input files, and an output file */

    static FILE *fpi1, *fpi2, *fpi3, *fpout;

    /* makeprl: Build utility
    *
    * Combines two binary images into Digital Research .PRL format.
    *
    * Note: The second image will be used for the binary data. It should
    * therefore be ORGed at 100h for PRL, RSX and FID files; and 000h for
    * SPR files. The first image can be ORGed anywhere as long as it isn't the
    * same place as the second image.
    */

    /*
    * Write the bit b to a stream of bits fp. Note: At the end of the file
    * creation process, there may be up to 7 bits of data left in this routine's
    * buffer. Write 7 zero bits to make sure all data have been written.
    *
    */

    void addbit(FILE *fp, byte b)
    {
    static byte m = 0x80; /* Mask. MSB comes first */
    static byte c = 0; /* Count of bits (write byte when
    we have 8) */
    static byte o = 0; /* Output byte under construction */

    if (b) o |= m; else o &= (~m); /* Write the bit */
    m = (m >> 1); /* Mask to next position */
    c++; /* Next count */
    if (c == 8)
    {
    fputc(o, fp); /* Write the byte */
    m = 0x80; /* Reset variables */
    c = 0;
    o = 0;
    }
    }


    /* And the only other function in the program is main() */


    int main(int argc, char **argv)
    {
    byte p,q;
    int i, j; /* General purpose */
    long count = 0; /* Length of binary image */

    if (argc < 5)
    {
    fprintf(stderr,"Syntax: makeprl image.0 image.1 "
    "header image.prl\n");
    exit(1);
    }
    fpout = fopen(argv[4], "wb"); /* Open output file */
    if (!fpout)
    {
    perror(argv[4]);
    exit(1);
    }

    fpi1 = fopen(argv[1], "rb"); /* Open input files */
    if (!fpi1)
    {
    fclose(fpout);
    perror(argv[1]);
    exit(1);
    }

    fpi2 = fopen(argv[2], "rb");
    if (!fpi2)
    {
    fclose(fpout);
    fclose(fpi1);
    perror(argv[2]);
    exit(1);
    }

    /* Header image file - if there is none, then supply /dev/zero here */

    fpi3 = fopen(argv[3], "rb");
    if (!fpi3)
    {
    fclose(fpout);
    fclose(fpi1);
    fclose(fpi2);
    perror(argv[3]);
    exit(1);
    }

    /* Copy the PRL header, packing it out to 256 chars with zeroes */

    for (i = j = 0; i < 256; i++)
    {
    if (j != EOF) j = fgetc(fpi3);
    if (j == EOF) fputc(0, fpout); /* PRL header */
    else fputc(j, fpout);
    }
    /* Copy the byte image from file 2 to PRL file */

    while (!feof(fpi2))
    {
    i = fgetc(fpi2);
    if (i == EOF) continue;
    fputc(i, fpout);
    ++count;
    }
    fseek(fpi2, 0L, SEEK_SET); /* Rewind file 2 */

    /* Compare byte-by-byte, and if they are different then put a 1 in
    * the relocation map */

    while (!feof(fpi2))
    {
    int i = fgetc(fpi2);
    if (i == EOF) break;

    p = i;
    i = fgetc(fpi1);
    if (i == EOF) break;
    q = i;

    addbit(fpout, (p != q));
    }
    /* Flush the bitwise output buffer */

    for (p = 0; p < 7; p++) addbit(fpout, 0);
    fclose(fpi1);
    fclose(fpi2);
    fseek(fpout, 1L, SEEK_SET); /* Write PRL file length */
    fputc((count & 0xFF), fpout);
    fputc((count >> 8), fpout);
    fclose(fpout);

    return 0;
    }



    --
    ------------- http://www.seasip.demon.co.uk/index.html --------------------
    John Elliott |BLOODNOK: "But why have you got such a long face?"
    |SEAGOON: "Heavy dentures, Sir!" - The Goon Show
    :-------------------------------------------------------------------------)

  8. Re: Processor Tech ENT file utility

    John Elliott wrote:

    > Julian Albo wrote:
    > : I wrote several years ago a little utility to create relocatable code.
    > : There is not a big job, you make two assemblies with two different ORG
    > : (better if the difference is not a multiple of 256), compare byte by
    > : byte the two files, check that the differences are groups of two bytes
    > : and the difference is always the same (and corresponds to the difference
    > : of the ORG, if the program knows it). Fill a table with the addresses of
    > : the differences, or create a bitmap that marks it. Replace the positions
    > : marked for relocation with the value corresponding to an ORG 0 (or do
    > : the assembly of one of the files with this ORG) to simplify the
    > : relocation code.
    >
    > If you're constructing a PRL file, on the other hand, it's better if you
    > do ORG them 256 bytes apart. Here's a program that generates a PRL from
    > three files - one ORGed at 0, one ORGed at 1, and an optional one
    > containing the loader. Something like:


    Yes, I was doing this automatically in Pasmo (mi Z80 cross assembler) when
    the option to generate PRL was invoked. In the current (still unfinished)
    version that generates relocatable modules and links them this is no more
    required.

    I was thinking about adding an option to generate autorelocatable code, your
    idea of optionally specify the code for relocation is interesting, maybe I
    add it in a later version.

    By the way, the Pasmo version under development can generate and link REL
    files (no COMMON sections until a later version). I hope this will be
    useful for CP/M programmers that does not dislike cross tools.

    --
    Salu2

  9. Re: Processor Tech ENT file utility

    AROBASE.TXT
    -----------

    Ok. I am now back home.

    Let us try to remember the problem. A man whose name I don't remember posted
    on the comp.os.cpm Newsgroup a message about a RUNENT (why not LOADENT?)
    utility. If I have well understood, ENT files are simply an old-style dump
    (that is to say: without the ASCII display, only the address and the hex
    bytes.), and they end by the reserved character "/". They were used by
    SOLOS/cutter, not CP/M: that's why I never heard about them.

    However, I am quite familiar with the "Intel HEX file format", as
    demonstrated
    by all those BASIC programs I have produced over the year dealing with it
    and
    its variations (LOAD, UNLOAD, LOADH86, LOADPRL, LOADHEX, SAVEHEX, etc).

    It so happen that, on the Internet, there are a few programs that are only
    available as a dump... Recently, such was the case for the Rohde & Schwarz
    LAS-BASIC. I adapted one DMPCOM program of mine, getting one DMPCMD
    (LASBASIC
    is a CP/M-86 8086 ComManD file), which enabled me to get LAS-BASIC on my
    system (after finding that some characters had been dropped when the dump
    was
    generated, as reported on the comp.os.cpm Newsgroup a few weeks ago).

    So, since I don't understand or know all the internals of SOLOS/Cutter (and
    am
    quite tired, those days), I simply offer my DMPCOM program, to show how
    simple
    the task of loading one dump into memory can be.

    10 REM DMPCOM.BAS by Emmanuel ROCHE
    20 :
    30 PRINT
    40 'INPUT "DMP-to-COM> Enter DMP File Name: " ; name$
    50 ' name$ = "SOLOS"
    60 PRINT
    70 name1$ = name$ + ".DMP"
    80 name2$ = name$ + ".COM"
    90 OPEN "I", #1, name1$
    100 OPEN "R", #2, name2$, 1
    110 FIELD #2, 1 AS db2$
    120 lc = 1
    130 INPUT #1, rec$
    140 IF LEFT$ (rec$, 1) = ":" THEN GOTO 190
    150 PRINT rec$
    160 GOTO 130
    170 :
    180 INPUT #1, rec$
    190 rl$ = MID$ (rec$, 2, 2)
    200 rl = VAL ("&H" + rl$)
    210 IF rl = 0 THEN GOTO 550
    220 cs = rl
    230 la$ = MID$ (rec$, 4, 4)
    240 PRINT la$ ": " ;
    250 la = VAL ("&H" + la$) + &H100
    260 IF lc = 1 THEN fa = la
    270 alpha$ = ""
    280 FOR i = 1 TO rl
    290 db$ = MID$ (rec$, 8+i*2, 2)
    300 PRINT db$ " " ;
    310 db = VAL ("&H" + db$)
    320 cs = cs + db
    330 al$ = CHR$ (db)
    340 LSET db2$ = al$
    350 PUT #2
    360 IF (db < &H20) OR (db > &H7E) THEN al$ = "."
    370 alpha$ = alpha$ + al$
    380 la = la + 1
    390 NEXT i
    400 PRINT alpha$
    410 hb = INT (la / 256)
    420 lb = la - hb * 256
    430 IF lb = 0 THEN lb = lb - 1
    440 cs = cs + hb + lb - (rl + 1)
    450 cs$ = RIGHT$ (HEX$ (&HFFF - cs), 2)
    460 ' IF cs$ <> RIGHT$ (rec$, 2) THEN GOTO 490
    470 lc = lc + 1
    480 GOTO 180
    490 :
    500 PRINT
    510 PRINT CHR$ (7) ; "Checksum Error in line: " ; la$
    520 PRINT
    530 END
    540 :
    550 PRINT
    560 PRINT "First address: " ; HEX$ (fa, 4)
    570 PRINT "Last address: " ; HEX$ (la - 1, 4)
    580 PRINT "Bytes read: " ; HEX$ (la - fa, 4)
    590 PRINT "Records read: " ; HEX$ ( (la - fa) / 128, 2)
    600 PRINT
    610 CLOSE
    620 END

    This program was an adaptation of my LOAD program: that's why it is checking
    for a line starting with a ":". (That's also why it displays stuff like a
    regular dump while running, and finish by displaying statistics LOAD-style.)
    Of course, an adaptation of this program dealing with ENT files should be
    modified.

    Just thinking, I think that there are 3 potential problems with ENT files:

    1) The end-of-data character ("/"). I think that it should ALWAYS be put on
    a
    separate line, not as a last character on a line.

    2) The problem of the number of hex bytes to read. The Intel HEX file format
    contains a byte indicating this number. In my oldest HEX file, this is not
    the
    usual 16, but 24... (This was done to use the ASR-33 Teletype line width to
    its fullest...) Unfortunately, it is obvious that a dump has a fixed format:
    any deviation from the "standard" will oblige you to change the program...

    3) The Intel HEX file format has a separate "record" indicating several
    things
    like if the file need to be executed after loading it into RAM, and if so at
    which address... Obviously, a dump has not such an information.

    So, as explained with LAS-BASIC, I found by experience that dump files are a
    very bad way to transfer binary data, while I have had no problem with Intel
    HEX files during the last 20 years.

    (I remember that there was also a discussion about relocating a program but,
    in this case, the program is so small (after a while, you "see" how to
    translate in ASM the BASIC lines. In addition, this is a simple "sequential
    I/O program", that is to say: the subject of a chapter in the MAC guide. All
    the necessary macros needed to program such a loader are in the MAC guide,
    and
    have been debuggued for the last 30 years... UNLOAD, which does the reverse
    of
    RUNENT, is one page and half long...) that I doubt that relocation is
    needed.
    Simply assemble it at the address where it is to be run on the SOLOS/Cutter.
    (If you need to have an optional "load address", UNLOAD happens to have one.
    The standard format is "UNLOAD filename", but you can optionaly type "UNLOAD
    filename bias". All this in a page and half.))

    MAC is the standard 8080 macro-assembler for CP/M 2.2.

    I have no idea what are the standard tools for SOLOS/Cutter, or how
    compatible
    with CP/M it is.

    Well, this is already quite a long message.

    In short: the logic of a program taking data from a dump and either loading
    them in memory or into a file (CP/M is file-oriented) is simple. If you have
    no idea how to do something, debug the algorithm with a BASIC interpreter,
    then translate the algorithm into ASM. After a while, you will be able to
    restrict the BASIC commands used to ones easily translatable to ASM. This
    way,
    you spend less time debugguing at the ASM level. The most important thing is
    the algorithm. But the algorithm depends upon the data structures used, and
    a
    dump is simply a very, very bad data structure, providing not enough
    information for transferring and/or checking the contents of a binary file.

    After that, moving the program at its right running address and jumping to
    it
    are obvious.

    Hope to have helped you. Sorry, but I am too busy to do it for you, and know
    (almost) nothing about the SOLOS/Cutter.

    Yours Sincerely,
    "French Luser"


    EOF



  10. Re: Processor Tech ENT file utility

    OK, thanks for the interest...
    Let me answer some questions and rehash just
    what the intent and operation of the RUNENT
    program are.

    1) It's called RUNENT because that's what it does.
    It does not convert an ENT file into a COM file
    or a HEX file or any other file. I don't want to
    be bothered. I just want a CP/M disk full of ENT
    files that I can run without any other effort.
    2) I'm not creating ENT files or proposing that it is
    a preferable format. There exists a significant
    collection of Processor Technology software in this
    format. I want to run this software without having
    to have a tape player or another computer to feed
    the programs into the Solos/Cutter monitor program.
    3) Why not convert them to COM files? Because, most of
    this software was written with no thought towards
    CP/M. The majority of the programs are ORG'd at
    0000H and a number of those that are not are ORG'd
    at other strange addresses, not at 0100H where CP/M
    wants to load COM files.
    4) OK, then what's being relocated? My code is being
    relocated. The code that does the work of reading
    through the files and translating the ASCII characters
    into numeric values that are then stored in memory.
    Because most of the ENT files start at 0000H, it seemed
    simplest to me to put my code at the top of the TPA
    (which varies from system to system) and use the rest
    of the TPA to load the ENT file image. Note that all
    ENT file address specifications below BFFFH are incremented
    by 0100H then, after the load is complete, the whole
    TPA is moved down. The ENT file memory image ends up
    where it was originally intended, we just avoid trashing
    the first 256 bytes until we don't need CP/M any more,
    that is, we're done reading the file(s).
    5) So, what's your problem then? Nothing really I guess.
    I just wondered how DDT does the trick. I went through
    a lot of the CP/M user group files that are available on
    the net and couldn't find an example. My attempts to
    dissassemble DDT were not particularly useful. Anyway,
    RUNENT works, by my own testing and by the use of several
    others. The only enhancement it could use would be
    some code to try to prevent the relocated work code from
    overwriting itself if it is presented with an ENT file
    that would do so.
    6) Why two ENT files? The intent of this is to allow
    the operation of the "music.ent" program. This program
    requires that both it and an ENT file containing the
    data for the composition to be played be loaded at the
    same time.

    Bill Sudbrink



  11. Re: Processor Tech ENT file utility


    Bill Sudbrink wrote:
    > OK, thanks for the interest...

    I don't know if it would be of any help,
    but are you familiar with the solent utility?
    see http://home.alphalink.com.au/~edsa/
    Phil


  12. Re: Processor Tech ENT file utility

    "Bill Sudbrink" wrote:

    > OK, thanks for the interest...
    > Let me answer some questions and rehash just
    > what the intent and operation of the RUNENT
    > program are.


    Ha! Ok. I now understand better what ENT files are.

    So, your main problem is that you cannot use the "Page Zero" of CP/M (I assume
    that you use CP/M 2.2, since you never mentioned which version you are using).

    Since you can no longer user DBUF (the standard buffer used by CP/M to
    read/write to the floppy), don't forget that you can relocate it to somewhere
    else in memory... Of course, it would be a good idea if this place happened to
    be inside your RUNENT utility, in the top of RAM.

    Normally, once a program is running, it can do anything it wants, so it should
    be safe to write over the Page Zero. I would just save a copy of it (the "Page
    Zero") inside RUNENT, then copy it back to its page before exiting (by the
    way, are you able to return to CP/M ("warm start"), or do you need to reboot
    ("cold start")?

    You did not say if you are familiar with CP/M and/or assembly language
    programming (and if 8080 or Z-80), or familiar with absolute, relocatable, or
    macro fashion. In short, CP/M uses 2 part of a floppy to store files: the
    directory and the data blocks. Any CP/M program dealing with files must, thus,
    check for 2 things:

    1) If a file entry is present in the directory (else "File Not Found")

    2) If the file contains actual data (else "No Records Exist (zero-length
    file)")

    Those are the first 2 steps that any CP/M program dealing with a file must
    perform before doing any processing.

    So, to continue this discussion, the following steps should be:

    3) Copy Page Zero inside RUNENT

    4) Establish a new DBUF inside RUNENT

    5) Now, process ENT file by reading its address and poking its bytes there

    6) Either copy back Page Zero to its place, or jump to 0000H if ENT file need
    to be run by jumping there (this shows the problem that all the RST points are
    in page zero, and CP/M uses 2 of them: you did not say how ENT files access
    the SOLOS/Cuter: do they also use RST points, or do they use absolute
    address?).

    Here ends the discussion, since we cannot make any decision without knowing
    the above.

    (Another remark: when you debug some programs, you find that, each time you
    load a copy of the program, it copies a copy of itself under the previous
    copy... It could be a good idea to always load RUNENT just below the CCP or
    the BDOS.)

    To finish: what software are you using? There are at least 4 or 5 ways of
    creating PRL files: some are easier than others, but depend upon the assembler
    used.

    Yours Sincerely,
    "French Luser"




  13. Re: Processor Tech ENT file utility

    > "Bill Sudbrink" wrote:
    >
    > > OK, thanks for the interest...
    > > Let me answer some questions and rehash just
    > > what the intent and operation of the RUNENT
    > > program are.


    French Luser wrote:
    >
    > Ha! Ok. I now understand better what ENT files are.
    >
    > So, your main problem is that you cannot use the "Page Zero" of CP/M ...
    >
    > Normally, once a program is running, it can do anything it wants, so it should
    > be safe to write over the Page Zero. I would just save a copy of it (the "Page
    > Zero") inside RUNENT, then copy it back to its page before exiting (by the
    > way, are you able to return to CP/M ("warm start"), or do you need to reboot
    > ("cold start")?


    Actually, if you read Sudbrink's post again, and his code, you might
    see that he only uses CP/M twice. Once, to save .ENT files on a
    diskette (this he does not describe but somebody had to put those files
    on a CP/M diskette); and again (with RUNENT) to load those files to run
    them. HE DOES NOT "USE" CP/M otherwise., even to RUN THE PROGRAM. The
    "program" is not a CP/M program, he is not trying to convert these .ENT
    files to CP/M programs, the programs do not call upon BIOS or BDOS. OK?

    After he's done running his .ENT program, I presume he cold boots into
    CP/M, or turns off the computer. So there is no need to "preserve"
    CP/M's page 0, or any other part of CP/M that is not already saved on
    the CP/M boot tracks. Indeed, his ENT program or the PT OS may clobber
    CP/M anyway. I hope he checks if he's loading the file over the
    relocated RUNENT (which he'd put below BDOS anyway, possibly below the
    CCP which is unnecessary).

    One question you could answer for Sudbrink is whether he needs to save
    page zero at all! You almost answer that. His code's method is to load
    the .ENT file from diskette (using CP/M) at a 100H offset, then to move
    the loaded file down in memory (using only his code) just before
    execution. The fact that it "clobbers" page zero at that point is MOOT
    as he ignores CP/M altogether by then and henceforth.

    But my recollection is that BDOS (or was it CCP?) uses the area between
    0080H and 00FFH as a stack area. If so that's another reason to avoid
    overwriting page 0 until CP/M is no longer needed. And I seem to recall
    that parts of page 0 hold FCB data; that's important of course to
    RUNENT as it needs CP/M to read files (until the file is read into
    memory). "Luser", if you can inform him about these issues, which you
    know better than I, you may uncover possible error conditions. He
    should verify early on if CP/M is using a stack area within the memory
    space where he's loading .ENT code.

    "Luser", I think you suggest he may be able to move the CP/M file read
    buffer around and read directly into memory. I'm not sure that is a
    big gain, but it's your idea to persue.

    Sudbrink's utility is an interesting program, as it's a nonstandard use
    of CP/M; namely, to load a file or two and run them "over" CP/M. It's
    informative and challenging when you write a program in one operating
    system to support another.

    That's my response to "Luser's" post. I have another idea about this
    RUNENT program.

    To avoid the "clobber page zero" problem, how about "delaying" the load
    of the first block of the .ENT file, untill after the LAST block is
    read into memory? You could for instance open the file and save the
    first block in a high memory buffer. Then load the rest in place, no
    offset. After the end of file you do your cleanup, then as a last step
    move the buffered first block to lowest memory and then execute the
    code in place.

    It's a bit of code, and a 256-byte buffer, but it may not be much more
    than the code needed to "reshuffle" the offset-loaded file within
    memory. (And you'd use that 256 bytes anyway in the "offset" scheme
    wherein all the code was loaded that much higher.) Note that this
    method does not specify "only if page zero"; you can treat ALL first
    blocks the same way, even if it's only necessary for .ENT programs
    which start at zero. Finally, this change is not needed for the SECOND
    ..ENT file of a pair, if you assume it will never be loaded below the
    first - Sudbrink knows more about that condition, where you need to
    load a program to run the program.

    Herb Johnson


    Herbert R. Johnson, New Jersey USA
    web site
    domain mirror
    my email address: hjohnson AAT retrotechnology DOTT com
    if no reply, try in a few days: herbjohnson ATT comcast DOTT net
    "Herb's Stuff": old Mac, SGI, 8-inch floppy drives
    S-100 IMSAI Altair computers, docs, by "Dr. S-100"


  14. Re: Processor Tech ENT file utility

    On 10 Jul 2006 07:58:47 -0700, "Herb Johnson"
    wrote:

    >> "Bill Sudbrink" wrote:
    >>
    >> > OK, thanks for the interest...
    >> > Let me answer some questions and rehash just
    >> > what the intent and operation of the RUNENT
    >> > program are.

    >
    >French Luser wrote:
    >>
    >> Ha! Ok. I now understand better what ENT files are.
    >>
    >> So, your main problem is that you cannot use the "Page Zero" of CP/M ...
    >>
    >> Normally, once a program is running, it can do anything it wants, so it should
    >> be safe to write over the Page Zero. I would just save a copy of it (the "Page
    >> Zero") inside RUNENT, then copy it back to its page before exiting (by the
    >> way, are you able to return to CP/M ("warm start"), or do you need to reboot
    >> ("cold start")?

    >
    >Actually, if you read Sudbrink's post again, and his code, you might
    >see that he only uses CP/M twice. Once, to save .ENT files on a
    >diskette (this he does not describe but somebody had to put those files
    >on a CP/M diskette); and again (with RUNENT) to load those files to run
    >them. HE DOES NOT "USE" CP/M otherwise., even to RUN THE PROGRAM. The
    >"program" is not a CP/M program, he is not trying to convert these .ENT
    >files to CP/M programs, the programs do not call upon BIOS or BDOS. OK?
    >
    >After he's done running his .ENT program, I presume he cold boots into
    >CP/M, or turns off the computer. So there is no need to "preserve"
    >CP/M's page 0, or any other part of CP/M that is not already saved on
    >the CP/M boot tracks. Indeed, his ENT program or the PT OS may clobber
    >CP/M anyway. I hope he checks if he's loading the file over the
    >relocated RUNENT (which he'd put below BDOS anyway, possibly below the
    >CCP which is unnecessary).
    >
    >One question you could answer for Sudbrink is whether he needs to save
    >page zero at all! You almost answer that. His code's method is to load
    >the .ENT file from diskette (using CP/M) at a 100H offset, then to move
    >the loaded file down in memory (using only his code) just before
    >execution. The fact that it "clobbers" page zero at that point is MOOT
    >as he ignores CP/M altogether by then and henceforth.
    >
    >But my recollection is that BDOS (or was it CCP?) uses the area between
    >0080H and 00FFH as a stack area. If so that's another reason to avoid
    >overwriting page 0 until CP/M is no longer needed. And I seem to recall
    >that parts of page 0 hold FCB data; that's important of course to
    >RUNENT as it needs CP/M to read files (until the file is read into
    >memory). "Luser", if you can inform him about these issues, which you
    >know better than I, you may uncover possible error conditions. He
    >should verify early on if CP/M is using a stack area within the memory
    >space where he's loading .ENT code.


    Nope not stack area. It's the default FILE CONTROL BLOCK and also
    the Command string is buffered down there. All of that is relocatable
    by any transient program including the page0 vectors. Saving the few
    bytes in high ram is trivial and the BIOS can rewrite it if a call is
    made to COLDBOOT (assumes the bios is not overwritten) otherwise
    reset and jump to bootrom.

    >"Luser", I think you suggest he may be able to move the CP/M file read
    >buffer around and read directly into memory. I'm not sure that is a
    >big gain, but it's your idea to persue.
    >
    >Sudbrink's utility is an interesting program, as it's a nonstandard use
    >of CP/M; namely, to load a file or two and run them "over" CP/M. It's
    >informative and challenging when you write a program in one operating
    >system to support another.
    >
    >That's my response to "Luser's" post. I have another idea about this
    >RUNENT program.
    >
    >To avoid the "clobber page zero" problem, how about "delaying" the load
    >of the first block of the .ENT file, untill after the LAST block is
    >read into memory? You could for instance open the file and save the
    >first block in a high memory buffer. Then load the rest in place, no
    >offset. After the end of file you do your cleanup, then as a last step
    >move the buffered first block to lowest memory and then execute the
    >code in place.
    >
    >It's a bit of code, and a 256-byte buffer, but it may not be much more
    >than the code needed to "reshuffle" the offset-loaded file within
    >memory. (And you'd use that 256 bytes anyway in the "offset" scheme
    >wherein all the code was loaded that much higher.) Note that this
    >method does not specify "only if page zero"; you can treat ALL first
    >blocks the same way, even if it's only necessary for .ENT programs
    >which start at zero. Finally, this change is not needed for the SECOND
    >.ENT file of a pair, if you assume it will never be loaded below the
    >first - Sudbrink knows more about that condition, where you need to
    >load a program to run the program.


    Generally the .ENT or other relocatable program is no differnt than
    back when doing things like running NS* Dos as a CP/M transient
    (or the reverse!). There is obvious housekeeping to be done and
    likely depending on whats being done you can make CP/M work
    for you rather than consider it as something to overcome.

    It can be handy to know the program and where it like to live bit if
    its relocatable that should not be an issue as you _can_ relocate it.
    Programs like early 8K MSbasic were often supplied in absolute
    form and if it expects to be at 0000 it's something to deal with.
    This was often a problem for much of the non disk software that
    existed off the CP/M (or other OS) base.

    Generally where the code runs in ram these days is less an issue
    than what and were the IO is expected to be. The reason I say this
    is most sims and real systems have 64k of ram available. At that
    point the problem is not CP/M or even OS related. For example
    running TRS80(mod-1) Level-II basic on the average Z80 S100
    crate will be difficult as it expects Video ram and Keyboard
    (memory mapped) at addresses that are in the way for most
    other OSs. That's a challenge.

    Allison


    >Herb Johnson
    >
    >
    >Herbert R. Johnson, New Jersey USA
    > web site
    > domain mirror
    >my email address: hjohnson AAT retrotechnology DOTT com
    >if no reply, try in a few days: herbjohnson ATT comcast DOTT net
    >"Herb's Stuff": old Mac, SGI, 8-inch floppy drives
    >S-100 IMSAI Altair computers, docs, by "Dr. S-100"



  15. Re: Processor Tech ENT file utility

    On 2006-07-10, nospam@nouce.bellatlantic.net
    wrote:
    > On 10 Jul 2006 07:58:47 -0700, "Herb Johnson"
    > wrote:
    >>But my recollection is that BDOS (or was it CCP?) uses the area between
    >>0080H and 00FFH as a stack area.

    >
    > Nope not stack area. It's the default FILE CONTROL BLOCK and also
    > the Command string is buffered down there.


    Default FCB is at 005CH. 0080H through 00FFH contain the command tail
    and the stack (stack starts at 00FFH and grows towards 0080H).

    But I could be wrong. I often am.
    --
    roger ivie
    rivie@ridgenet.net

  16. Re: Processor Tech ENT file utility

    Roger Ivie wrote:
    : Default FCB is at 005CH. 0080H through 00FFH contain the command tail
    : and the stack (stack starts at 00FFH and grows towards 0080H).

    Under CP/M 3, the stack starts at the top of the TPA. But if you run a
    program in SID the stack grows down from 0100h. Therefore it's a good idea
    to move the stack to the top of memory explicitly - otherwise, the first
    time you debug in SID and something overwrites the buffer at 80h, boom.

    --
    ------------- http://www.seasip.demon.co.uk/index.html --------------------
    John Elliott |BLOODNOK: "But why have you got such a long face?"
    |SEAGOON: "Heavy dentures, Sir!" - The Goon Show
    :-------------------------------------------------------------------------)

  17. Re: Processor Tech ENT file utility

    On Mon, 10 Jul 2006 19:41:57 GMT, Roger Ivie
    wrote:

    >On 2006-07-10, nospam@nouce.bellatlantic.net
    >wrote:
    >> On 10 Jul 2006 07:58:47 -0700, "Herb Johnson"
    >> wrote:
    >>>But my recollection is that BDOS (or was it CCP?) uses the area between
    >>>0080H and 00FFH as a stack area.

    >>
    >> Nope not stack area. It's the default FILE CONTROL BLOCK and also
    >> the Command string is buffered down there.

    >
    >Default FCB is at 005CH. 0080H through 00FFH contain the command tail
    >and the stack (stack starts at 00FFH and grows towards 0080H).
    >
    >But I could be wrong. I often am.


    The space from 80h to FFh is the default DMA location. Its usually not
    used save for some CP/M apps will use it as a buffer. Programitcally
    under CP/M it's not a required area once the CCP has loaded and
    run a user program. However as a convenince to the programmer
    it is set up with the command tail if the users program cares to parse
    it.

    For V2.2 and plus the stack actually lives between the Bdos and the
    BIOS in the BDOS data area. That's the BDOS stack area, The CCP
    has it's own as well and most apps set their own stack area unless
    they use the default (the one the CCP uses which is small). The bios
    will set it's own stack space and preserve the return(usually BDOS)
    stack space if it needs it. It pays to be careful.

    DDT and SID/zsid set the stack to other places and also have a default
    for the debug stack if the user program being debugged hasn't set a
    specific stack space.

    CP/M page 0 locations (those used by CP/M or DDT). Any location not
    explicity mentioned is not used byt CP/M but may be used by user
    custom BIOS or other programming.

    0000-0002 Jump to warm start
    0003 IObyte (if used)
    0004 Default drive (0-A....15=P)
    0005-0007 Jump to bdos (standard BDOS entry)

    0038-003a RST7 for DDT

    005c--007c Default FCB
    007d-007f Optional random record position (part of FCB)
    0080-00ff Default 128 byte disk buffer
    (also contains command line from CCP)

    Straight from the book, CP/M Alteration Guide V2.

    Allison


  18. Re: Processor Tech ENT file utility

    I found this on the Internet. Is it relevant?

    Yours Sincerely,
    "French Luser"


    ====================
    BOOT.ASM
    BOOT.ENT
    ====================

    This is a little utility to allow programs that are normally
    loaded at 0000H to be run under CP/M. The source code has
    directions on how to use it (as does the program when it is run).


    *
    * <<< ::: SOL-20 BOOT BLOCK PROGRAM - BOOT.ASM ::: >>>
    *
    ORG 00100H
    XRA A ; CLEAR SCREEN
    OUT 0FEH
    OUT 0C8H
    CALL PERSE
    CALL CRLF
    START: JMP STAR1 ; BYPASS THE MESSAGES
    STAR1: LXI H,BEGIN ; JUMPER OUT ORIGINAL JUMP
    SHLD START+1
    LXI H,MSG1 ; INSTRUCTIONS
    CALL MSG
    *
    BEGIN: LXI H,MBLOK ; SET UP FOR MOVE RE-LOCATION
    LXI D,0C900H
    LXI B,MBLOK+48
    LXI SP,0CBE9H ; SET STACK POINTER AS EXPECTED
    XRA A ; FORCE SCREEN OPERATIONS
    STA 0C807H
    *
    MOVIT: MOV A,M ; FETCH DATA TO BE MOVED
    STAX D ; STORE IN NEW LOCATION
    MOV A,H ; GET "HIGH" ADDRESS
    CMP B ; LAST ADDRESS?
    JNZ MOVON ; ... NO
    MOV A,L ; GET "LOW" ADDRESS
    CMP C ; LAST ADDRESS?
    EXIT: JZ CLEAR ; ... YES, MOVE IT TO 0000H
    MOVON: INX H ; ... NO, ADVANCE "FROM" POINTER
    INX D ; ADVANCE "TO" POINTER
    JMP MOVIT
    *
    CLEAR: LXI D,00200H ; 1ST ADDRESS TO CLEAR
    LXI B,0A000H ; LAST ADDRESS TO CLEAR
    CLRIT: XRA A
    STAX D
    MOV A,D
    CMP B ; HI PART = LAST ADDRESS?
    JNZ CLRON ; ... NO
    JMP FIN ; ... YES, JUMP TO SOLOS
    CLRON: INX D
    JMP CLRIT
    *
    DB ' '
    *
    EOF: DW 0FF3FH ; EOF ADDRESS
    DB ' '
    *
    FIN: LXI H,0C900H ; SOLOS CONSOLE
    SHLD EXIT+1 ; PATCH MEM MOVE EXIT
    JMP 0C004H ; JUMP TO SOLOS CONSOLE
    *
    DB ' '
    DB ' '
    MBLOK: DB 02AH ; LHLD EOF
    DW 00150H
    DB 044H ; MOV B,H
    DB 04DH ; MOV C,L
    DB 011H ; LXI D,0H
    DW 00000H
    DB 021H ; LXI H,200H
    DW 00200H
    ;MOVIT:
    DB 07EH ; MOV A,M
    DB 012H ; STAX D
    DB 07CH ; MOV A,H
    DB 0B8H ; CMP B
    DB 0C2H ; JNZ MOVON
    DW 0C918H
    DB 07DH ; MOV A,L
    DW 0FFFEH ; CPI 0FFH
    DB 0CAH ; JZ 0H
    DW 00000H
    ;MOVON:
    DB 023H ; INX H
    DB 013H ; INX D
    DB 0C3H ; JMP MOVIN
    DW 0C90BH
    *
    DB '* '
    DB '* '
    DB '* '
    DB '* '
    DB '* '
    DB '* '
    DB '* '
    *
    *
    * ::: MESSAGE OUTPUT ROUTINE :::
    *
    * H+L HAVE MSG'S ADDRESS, "0" ENDS MESSAGE.
    *
    MSG: MOV A,M ; GET A CHARACTER
    CPI 0 ; END-OF-MESSAGE ?
    RZ ; ... YES, YOUR DONE
    MOV B,A
    CALL SOUT ; OUTPUT IT
    INX H ; NEXT CHARACTER
    JMP MSG
    *
    *---------------------------------------------------------*
    *
    MSG1: DB '<*> SOL-20 BOOT LOADER FOR PROGRAMS THAT LOAD <*>'
    DW 0A0DH
    DB '<*> AT ADDRESS 0. LOAD THE PROGRAM AT ADDRESS <*>'
    DW 0A0DH
    DB '<*> 200. 0150 IS THE ADDRESS FOR THE END OF THE <*>'
    DW 0A0DH
    DB '<*> PROGRAM THAT YOU LOADED. FOR EXAMPLE: <*>'
    DW 0A0DH
    DB '<*> THE LAST ADDRESS WAS 0E42. ENTER IT PLUS <*>'
    DW 0A0DH
    DB '<*> 200 INTO 150 BACKWARDS. ( >EN 150: 42 10/ ) <*>'
    DW 0A0DH
    DB '<*> THEN EXECUTE ADDRESS 0 TO RETURN TO CP/M. <*>'
    DW 0A0DH
    DB '<*> TYPE: A>SAVE 16 TARG.COM (BOOT=100 BYTES) <*>'
    DW 0A0DH
    DB '<*> TO SAVE THE PROGRAM ON DISK WITH THE BOOT. <*>'
    DW 0A0DH
    DB 00H
    *
    *-------------------------------------------------------------*
    *
    *
    *#* EQUATES *#*
    *
    CRLF: EQU 0C2F9H ; LINE FEED + CARRIAGE RETURN ROUTINE
    PERSE EQU 0C0D5H ; ERASE SCREEN
    SOUT: EQU 0C019H ; SYSTEMS OUTPUT ROUTINE (OPORT)
    END



  19. Processor Technology's ENT File Specifications

    Processor Technology's ENT File Specifications

    I did a little search on the Internet, but could not find any functional
    description of the ENT file format.

    While searching, I noticed a FOCAL interpreter. Since it is one of my old
    programming languages, I downloaded it, along with an unknown 6.5K "Byte Shop
    BASIC" (for CP/M)?

    So, as far as I can determine from those 2 files, the ENT file format is:

    1) A first line containing either "EN 0" or "ENTER 0100".
    So, obviously, there is no fixed-form format.
    As far as I can see, "Enamoramiento Babe" should be valid,
    since (1) it starts with "EN" and (2) "Babe" is a valid hex address.

    2) The rest of the files are just a normal old-style dump
    (1234: 01 02 03 (...) 0E 0F)
    BUT the last byte of the dump (not modulo 16) is
    followed by a "/" character (then probably by the
    CP/M End-Of-File character (1A = Ctrl-Z)).

    Based on that, I quickly modified my DMPCOM.BAS program,
    and got a ENTCOM.BAS program, but I had a problem with
    the "/" character that was still not solved when I went to bed.
    I will probably have to modify all the logic of the program,
    just to process this character...

    Also, I have no idea how those files were generated, since the
    FOCAL interpreter has a single space between the ":" of the
    address and the first byte, while the unknown BASIC interpreter
    has 2 spaces... (Really not fixed format!)

    So, tonight, I will try to write a small BASIC utility based on those specs.

    If you know more than me about the ENT File Specs, and noticed an
    error, please speak up!

    Yours Sincerely,
    "French Luser"




+ Reply to Thread