Close

Fixing Grant Searle's File Package Program

A project log for Grant Searle's Z80 CP/M Design

I thought I would put this CP/M 2.2 Z80 project together. See what I can learn.

agpcooperagp.cooper 03/21/2021 at 02:170 Comments

Installing CP/M

Grant provides a CP/M file package (CPM211FilesPkg.txt) that can be uploaded using GTKTerm and "DOWNLOAD.COM". So getting CP/M working was easy.

Installing Custom Packages

Grant provides a MS Windows program called FilePackage.exe that can creates a custom HEX file packages that work with DOWNLOAD. Unfortunately, it does not work under Wine (Linux). Even on a Windows PC it does not work unless you register COMDLG32.OCX. To register COMDLG32.OCX:

1) Copy the file to c:\Windows\SysWOW64\comdlg32.ocx (for Windows 64 bit system)

2) Open a command window and run "regsvr32 c:\Windows\SysWOW64\comdlg32.ocx"

For a 32 bit windows system substitute  "SysWOW64" for "system32".

File Package Bug

File Package (and DOWNLOAD) have a bug in that they don't mark the end of the file. This is important for text files. Without the "end of file" (EOF) marker (^Z or 0x1a), the text file repeats part of the tail of the file. Not fatal but messy. You could patch DOWNLOAD (as the source is provide) to insert an EOFmarker but in my case I wrote a short C command line program (file2hex.c). It only converts one file at a time but you can archive the files first. I have uploaded USQ, UNARC, UNCR and UNZIP. The special i8080 UNZIP.COM version only works unzip.exe version 1.11 (yes it still can be found on the Internet).

If you are having problem uploading files, providing you have PIP and LOAD installed, then you can upload an iHEX8 file using:

1) A:PIP FILENAME.HEX=CON:

2) "Send RAW file" (FILENAME.HEX) in GTKTerm.

3) ^D to get the prompt back

4) A:LOAD FILENAME.HEX

Here is file2hex.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int next(FILE *,char *);
int main(int argc,char **argv) {
  int user;
  char to[14];
  char from[14];
  int ch,len,sum;
  FILE *fp1,*fp2;

  if (argc!=4) {
    printf("usage: ./file2hex.run usernumber filename.ext filename.hex\n");
  } else {
    strcpy(from,argv[2]);
    if ((fp1=fopen(from,"rb"))==NULL) {
      printf("file2hex: Source file %s not found\n", from);
    } else {
      strcpy(to,argv[3]);
      if ((fp2=fopen(to,"w"))==NULL) {
        printf("file2hex: Could not create destination file %s\n", to);
      } else {
        user=atoi(argv[1]);
        // fseek(fp1,0L,SEEK_END);
        // len=(char)ftell(fp1);
        // fseek(fp1,0L,SEEK_SET);
        sum=0;
        len=0;
        fprintf(fp2,"A:DOWNLOAD %s\r\n",from);
        fprintf(fp2,"U%d\r\n",user);
        fprintf(fp2,":");
        while ((ch=fgetc(fp1))!=EOF) {
          fprintf(fp2,"%02X",ch&0xff);
          sum+=ch;
          len++;
        }
        // Insert EOF  Marker if not end of record
        if (len%128!=0) {
          fprintf(fp2,"%02X",0x1a);
          sum+=0x1a;
          len++;
        }
        fprintf(fp2,">%02X%02X\r\n\r\n",len&0xff,sum&0xff);
        fclose(fp1);
        fclose(fp2);
      }
    }
  }
  return 0;
}

AlanX

Discussions