PowerShell script for converting files for uploading to RC2014 systems with CF Cards

220 views
Skip to first unread message

Jim Bailey

unread,
Jan 30, 2023, 2:04:34 AM1/30/23
to RC2014-Z80

Grant Searle had created a set of programs for transferring files from Windows computers to CP/M systems via serial transfer.  You use his packer Windows program to transform the original binary file into a hex formatted representation of the original binary file.  Mr. Searle was kind enough to publish the format of his file format, as such I created a PowerShell script to convert files compatible with his download.com format. 

This has been tested on Windows 7, 10, 11 (ARM) and I have been using it when setting up my own RC2014’s. 

I thought I’d share it incase others may find it useful.

Examples:
     fileconvert.ps1 -infile cpm22.sys -outfile cpm_hex.txt -fileappend
     fileconvert.ps1 -infile cpm22.sys -outfile cpm_hex.txt -userno 0 -fileappend
     fileconvert.os1 -infile cpm22.sys -console


Parameters:
 
     infile         - This specifies the file to be read for conversion
     outfile       -  This specifies the HEX file to be created or appended to
     fileappend - This causes the converted file to be added to the end of the output file.
     console     - This causes the file to be converted to HEX but it’s written to the screen instead of a file.
     userno       - Defines the CP/M user number (0-F) to be used, typically user 0 is correct.

 
To use this file the text below needs to be copied to a file who's file name has a .PS1 extension.  Then you would run the script from a PowerShell window.


<#
.SYNOPSIS
    Powershell script to convert a binary file into a RC2014 download.com hex formatted file. 

.DESCRIPTION
    Powershell script to convert a binary file into a hex file suitable for uploading to a RC2014 using Grant Searle download.com CP/M utility and specifications.  You specify a file to read and it's converted and sent console or an output file.  You can append several conversions to a single output file, which makes it easier for batch uploads to your flashcard.

 

    Example: fileconvert.ps1 -infile cpm22.sys -outfile cpm_hex.txt -fileappend
             fileconvert.ps1 -infile cpm22.sys -outfile cpm_hex.txt -userno 0 -fileappend
             fileconvert.os1 -infile cpm22.sys -console

 

    Created by Jim Bailey on July 15, 2020  (ver 1.0)

.PARAMETER infile
    This specifies the file to be read for conversion

.PARAMETER outfile
    This specifies the HEX file to be created or appeneded to

.PARAMETER fileappend
    This causes the converted file to be added to the end of the output file.

.PARAMETER console
    This causes the file to be converted to HEX but its written to the screen instead of a file.

    The append and outfile parameters will be ignored if the console is specified.

.PARAMETER userno
    Defines the CP/M user number (0-F) to be used, typically user 0 is correct.

#>
param(

    [Parameter(Mandatory=$true)][string]$infile,
    [Parameter(Mandatory=$false)][string]$outfile,
    [Parameter(Mandatory=$false)][switch]$fileappend = $false,
    [Parameter(Mandatory=$false)][switch]$console = $false,
    [Parameter(Mandatory=$false)][string]$userno = 0
)

$userno = $userno.ToUpper()
if (!($userno -match "^[0-9A-F]{1}$")) {
   write-output "Error: UserNo must be between a hex value between 0-F."
   write-output "       If not specified it defaults to zero."
   exit
}

if (Test-Path $infile) {
   $bytes = get-content $infile -encoding byte 

# Convert string from binarary data to Hex data, also create a var that contains the sum from each byte.
   foreach ($byte in $bytes)
   {
      $bytesum = $bytesum + $byte
      $byteinhex = [string]::Format("{0:X}", $Byte)
      $paddedhex += $byteinhex.PadLeft(2,"0")
   }

#Extract "low byte" of file count in hex
   $Bytecount = $bytes.count
   $bytecount = $bytecount.ToString("X").padleft(2,'0')
   $bytecount = $bytecount.substring($bytecount.Length-2,2)


# Extract "Low byte" of stream sum (poor man's CRC)
   $bytesum = $bytesum.ToString("X").padleft(2,'0')
   $bytesum = $bytesum.substring($bytesum.length-2,2) 

# Format and output in RC2014 download.com format
   $output = "A:DOWNLOAD $infile`r`nU$userno`r`n:$paddedhex>$bytecount$bytesum"

  
   if ($console) {
      write-output $output
   }  else {
      if ($fileappend -eq $true) {
         Out-File -FilePath $outfile -Append -InputObject $output -Encoding ASCII
      } else {
         if (!(Test-Path $outfile)) {
            Out-File -FilePath $outfile -InputObject $output -Encoding ASCII     
         } else {
            write-output "Error: Target/Destination file already exists.`r`n       Use the -fileappend option to add to an existing file."
         }
      }
   }
} Else {
   write-output "Error: '$infile' input file not found."
}

Richard Deane

unread,
Jan 30, 2023, 2:13:43 AM1/30/23
to rc201...@googlegroups.com
Thank you, should be useful. I shall try on powershell under Linux.

Richard


--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rc2014-z80/cef630c7-6302-4689-8d1a-9b15ef4e29dan%40googlegroups.com.

Jim Bailey

unread,
Feb 14, 2023, 1:50:57 AM2/14/23
to RC2014-Z80
Hello Richard, 

I am curious if the script worked with PowerShell in Linux?  I neglected to implement a feature that zero's out unused bytes at the end of the last sector.  While I doubt its needed, however it didn't take much to add it.  Below is he modified script that adds this feature.

<#
.SYNOPSIS
    Powershell script to convert a binaray file into a RC2014 download.com hex formatted file.  
.DESCRIPTION
    Powershell script to convert a binaray file into a hex file sutable for uploading to a RC2014 using Grant Searle download.com CP/M utility and specifications.  You specify a file to read and it's converted and sent console or an output file.  You can append several conversions to a single output file, which makes it easyer for batch uploads to your flashcard.


    Example: fileconvert.ps1 -infile cpm22.sys -outfile cpm_hex.txt -fileappend
             fileconvert.ps1 -infile cpm22.sys -outfile cpm_hex.txt -userno 0 -fileappend
             fileconvert.os1 -infile cpm22.sys -console
             fileconvert.os1 -infile cpm22.sys -console -padding

    Created by Jim Bailey on Feb 12, 2023  (ver 1.1)
.PARAMETER infile
    This specifices the file to be read for conversion
.PARAMETER outfile
    This specifices the HEX file to be created or appeneded to

.PARAMETER fileappend
    This causes the converted file to be added to the end of the output file.
.PARAMETER console
    This causes the file to be converted to HEX but its writeen to the sceeen instead of a file.
    The append and outfile paraeters will be ignored if the console is specificied.

.PARAMETER userno
    Defines the CP/M user number (0-F) to be used, typically user 0 is correct.
.PARAMETER padding
    Pads the any unused bytes of the last sector with zero's, based on a 128 byte sector size.

#>

param(
    [Parameter(Mandatory=$true)][string]$infile,
    [Parameter(Mandatory=$false)][string]$outfile,
    [Parameter(Mandatory=$false)][switch]$fileappend = $false,
    [Parameter(Mandatory=$false)][switch]$console    = $false,
    [Parameter(Mandatory=$false)][string]$userno     = 0,
    [Parameter(Mandatory=$false)][switch]$padding    = $false
)

$secpadding = "0" * 256
$bytecount  = 0
$bytepad    = 0


$userno = $userno.ToUpper()
if (!($userno -match "^[0-9A-F]{1}$")) {
   write-output "Error: UserNo must be between a hex value between 0-F."
   write-output "       If not specified it defaults to zero."
   exit
}


if (Test-Path $infile) {
   $bytes = get-content $infile -encoding byte

# Convert string from binarary data to Hex data, also create a var that contains the sum from each byte.
   foreach ($byte in $bytes)
   {
      $bytecount++

      $bytesum = $bytesum + $byte
      $byteinhex = [string]::Format("{0:X}", $Byte)
      $paddedhex += $byteinhex.PadLeft(2,"0")
   }

# Pad unused bytes in last 128-byte sector with zero's
if ($padding -eq $true) {
  $bytepad = (128 - ($bytecount % 128)) * 2
  $paddedhex += $secpadding.substring(0,$bytepad)

}

#Extract "low byte" of file count in hex
   $Bytecount = $bytes.count+($bytepad/2)

Richard Deane

unread,
Feb 14, 2023, 2:26:27 AM2/14/23
to rc201...@googlegroups.com
Sorry Jim, not tried the original yet. I will try your update today under Linux and let you know.

Richard 

Richard Deane

unread,
Feb 14, 2023, 4:28:14 AM2/14/23
to rc201...@googlegroups.com
Jim,

Sadly not working under Linux Powershell 7.3.2
========================================================================================
PS /home/testuser/Downloads> ./fileconvert.ps1 -infile zbasic.arc -outfile zbasic.pkg -userno 0 -fileappend
Get-Content: /home/testuser/Downloads/fileconvert.ps1:50
Line |
  50 |     $bytes = get-content $infile -encoding byte
     |                                            ~~~~
     | Cannot process argument transformation on parameter 'Encoding'. 'byte'
     | is not a supported encoding name. For information on defining a custom
     | encoding, see the documentation for the Encoding.RegisterProvider
     | method. (Parameter 'name')
InvalidOperation: /home/testuser/Downloads/fileconvert.ps1:74
Line |
  74 |     $bytesum = $bytesum.ToString("X").padleft(2,'0')
     |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | You cannot call a method on a null-valued expression.
InvalidOperation: /home/testuser/Downloads/fileconvert.ps1:75
Line |
  75 |     $bytesum = $bytesum.substring($bytesum.length-2,2)
     |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | You cannot call a method on a null-valued expression.
=========================================================================================

Cheers
Richard




Richard Deane

unread,
Feb 14, 2023, 5:23:43 AM2/14/23
to rc201...@googlegroups.com
Jim,

FYI - I tested your script under my WIN10 VM with Windows Powershell (default version 5.1.19041.2364) and it worked fine; however it fails with the same errors as Linux under Powershell v7.3.2 on Windows.
versions checked with command $PSVersionTable.
I am a novice at Powershell so I can't offer any suggestions as to why the script fails under newer powershell versions.

Cheers
RIchard




Richard Deane

unread,
Feb 14, 2023, 6:43:40 AM2/14/23
to rc201...@googlegroups.com
If I change -encode from byte to oem, and remove "X" from ToString, the script at least runs, but doesn't actually create the correct file. Not surprised because your "X" was there for a reason - it might give you a clue as to required changes, if you wish to fix it.

Richard


On Tue, 14 Feb 2023 at 06:51, Jim Bailey <jim.b...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages