Browse Source

Merge pull request #331 from wwarthen/dev

Merge Final v3.2
pull/335/head
Wayne Warthen 3 years ago
committed by GitHub
parent
commit
cd96ea7e26
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 61
      .github/workflows/commit.yml
  2. 106
      .github/workflows/release.yml
  3. 26
      .gitignore
  4. 6
      Binary/Apps/Clean.cmd
  5. 7
      Binary/Apps/Makefile
  6. 9
      Binary/Apps/ReadMe.txt
  7. 4
      Binary/Apps/Test/Clean.cmd
  8. 7
      Binary/Apps/Test/Makefile
  9. 16
      Binary/Apps/Test/ReadMe.txt
  10. 2
      Binary/Apps/Tunes/ReadMe.txt
  11. 11
      Binary/CPM3/Clean.cmd
  12. 7
      Binary/CPM3/Makefile
  13. 17
      Binary/CPM3/ReadMe.txt
  14. 8
      Binary/Clean.cmd
  15. 167
      Binary/DiskList.txt
  16. 6
      Binary/Makefile
  17. 35
      Binary/ReadMe.txt
  18. 218
      Binary/RomList.txt
  19. 10
      Binary/ZPM3/Clean.cmd
  20. 7
      Binary/ZPM3/Makefile
  21. 17
      Binary/ZPM3/ReadMe.txt
  22. BIN
      Binary/cpnos-wbw.sys
  23. 6
      Build.cmd
  24. 5
      Clean.cmd
  25. 131
      Doc/ChangeLog.txt
  26. 186
      Doc/Contrib/Flash4.txt
  27. BIN
      Doc/Contrib/How to Make Disk Images in Linux with DD Command.pdf
  28. BIN
      Doc/Contrib/Microsoft NASCOM BASIC.docx
  29. 39
      Doc/Contrib/PPI_Bus.txt
  30. 564
      Doc/DDTZ.doc
  31. 514
      Doc/FDU.txt
  32. BIN
      Doc/Hard Disk Anatomy.pdf
  33. BIN
      Doc/Microsoft Basic-80 Reference Manual v5.0.pdf
  34. 89
      Doc/ReadMe.txt
  35. BIN
      Doc/RomWBW Applications.pdf
  36. BIN
      Doc/RomWBW Architecture.pdf
  37. BIN
      Doc/RomWBW Disk Catalog.pdf
  38. BIN
      Doc/RomWBW Errata.pdf
  39. BIN
      Doc/RomWBW Getting Started.pdf
  40. BIN
      Doc/RomWBW ROM Applications.pdf
  41. BIN
      Doc/RomWBW System Guide.pdf
  42. BIN
      Doc/RomWBW User Guide.pdf
  43. BIN
      Doc/SIO+CTC Baud Rate Options.pdf
  44. 25
      Doc/Testing Notes.txt
  45. BIN
      Doc/UCSD p-System Users Manual.pdf
  46. BIN
      Doc/Z180 ASCI Baud Rate Options.pdf
  47. 765
      Doc/ZCPR-DJ.doc
  48. BIN
      Doc/qcp27.pdf
  49. BIN
      Doc/qdos27.pdf
  50. BIN
      Doc/qpm27.pdf
  51. 24
      Makefile
  52. 1250
      ReadMe.md
  53. 1221
      ReadMe.txt
  54. 49
      Readme.unix
  55. 1899
      Source/Apps/Assign.asm
  56. 56
      Source/Apps/Build.cmd
  57. 15
      Source/Apps/Clean.cmd
  58. 14
      Source/Apps/Dev/Build.cmd
  59. 7
      Source/Apps/Dev/Clean.cmd
  60. 10
      Source/Apps/Dev/Makefile
  61. 1
      Source/Apps/Dev/ReadMe.txt
  62. 32
      Source/Apps/Dev/dev.asm
  63. 2
      Source/Apps/FAT/Build.cmd
  64. BIN
      Source/Apps/FAT/FAT.com
  65. 4
      Source/Apps/FAT/Makefile
  66. 9
      Source/Apps/FAT/ReadMe.txt
  67. BIN
      Source/Apps/FAT/fat.com
  68. 8
      Source/Apps/FDU/Build.cmd
  69. 4613
      Source/Apps/FDU/FDU.asm
  70. 514
      Source/Apps/FDU/FDU.txt
  71. 6
      Source/Apps/FDU/Makefile
  72. 4757
      Source/Apps/FDU/fdu.asm
  73. 535
      Source/Apps/FDU/fdu.doc
  74. 11
      Source/Apps/Makefile
  75. 1040
      Source/Apps/Mode.asm
  76. 1732
      Source/Apps/RTC.asm
  77. 725
      Source/Apps/Survey.asm
  78. 16
      Source/Apps/Survey/Build.cmd
  79. 8
      Source/Apps/Survey/Clean.cmd
  80. 6
      Source/Apps/Survey/Makefile
  81. 830
      Source/Apps/Survey/survey.mac
  82. 978
      Source/Apps/SysCopy.asm
  83. 507
      Source/Apps/SysGen.z80
  84. 567
      Source/Apps/Test/2piotst/2piotst.mac
  85. 13
      Source/Apps/Test/2piotst/Build.cmd
  86. 8
      Source/Apps/Test/2piotst/Clean.cmd
  87. 8
      Source/Apps/Test/2piotst/Makefile
  88. 40
      Source/Apps/Test/Build.cmd
  89. 23
      Source/Apps/Test/Clean.cmd
  90. 11
      Source/Apps/Test/DMAmon/Build.cmd
  91. 6
      Source/Apps/Test/DMAmon/Clean.cmd
  92. 7
      Source/Apps/Test/DMAmon/Makefile
  93. 8
      Source/Apps/Test/DMAmon/Readme.txt
  94. 1220
      Source/Apps/Test/DMAmon/dmamon.asm
  95. 969
      Source/Apps/Test/DMAmon/util.asm
  96. 13
      Source/Apps/Test/I2C/Build.cmd
  97. 5
      Source/Apps/Test/I2C/Clean.cmd
  98. 8
      Source/Apps/Test/I2C/Makefile
  99. 132
      Source/Apps/Test/I2C/i2ccpm.inc
  100. 517
      Source/Apps/Test/I2C/i2clcd.asm

61
.github/workflows/commit.yml

@ -3,30 +3,67 @@ name: Commit Build
on: on:
push: push:
branches: branches:
- master
- '**'
tags-ignore: tags-ignore:
- v*
- '**'
jobs: jobs:
build:
buildLinux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/checkout@v2
- name: Make Slugs
uses: rlespinasse/github-slug-action@v4.4.1
- name: Checkout
uses: actions/checkout@v3.3.0
- name: Build - name: Build
run: | run: |
export TZ='America/Los_Angeles' export TZ='America/Los_Angeles'
sudo apt-get install libncurses-dev sudo apt-get install libncurses-dev
make
make clean
sudo apt-get install srecord
make dist
rm -rf .git* rm -rf .git*
- name: List Output
run: |
cd Binary
ls -l
find -type f -exec md5sum '{}' \;
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v3.1.1
with: with:
name: RomWBW-${{env.GITHUB_REF_SLUG}}-${{env.GITHUB_SHA_SHORT}}
name: RomWBW-${{env.GITHUB_SHA_SHORT}}-Linux
path: . path: .
buildMacOS:
runs-on: macOS-latest
steps:
- name: Make Slugs
uses: rlespinasse/github-slug-action@v4.4.1
- name: Checkout
uses: actions/checkout@v3.3.0
- name: Build
run: |
export TZ='America/Los_Angeles'
brew install srecord
make dist
rm -rf .git*
- name: List Output
run: |
cd Binary
ls -l
find . -type f -exec md5 -r -- '{}' +;
- name: Upload Artifact
uses: actions/upload-artifact@v3.1.1
with:
name: RomWBW-${{env.GITHUB_SHA_SHORT}}-MacOS
path: .

106
.github/workflows/release.yml

@ -1,8 +1,9 @@
name: Release Build name: Release Build
on: on:
release:
types: published
push:
tags:
- '**'
jobs: jobs:
build: build:
@ -10,42 +11,93 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3.3.0
- name: Create Package Label - name: Create Package Label
run: | run: |
echo GITHUB_REF: "$GITHUB_REF"
LABEL=`echo "$GITHUB_REF" | sed "s|^refs/tags/||"` LABEL=`echo "$GITHUB_REF" | sed "s|^refs/tags/||"`
echo "::set-env name=PKGLBL::$LABEL"
- name: Display Diagnostics
run: |
echo "PKGLBL=$LABEL" >> $GITHUB_ENV
echo PKGLBL: "$PKGLBL" echo PKGLBL: "$PKGLBL"
echo Upload URL: "${{github.event.release.upload_url}}" echo Upload URL: "${{github.event.release.upload_url}}"
echo GITHUB_TOKEN: "${{secrets.GITHUB_TOKEN}}" echo GITHUB_TOKEN: "${{secrets.GITHUB_TOKEN}}"
- name: Build - name: Build
run: | run: |
export TZ='America/Los_Angeles'
sudo apt-get install libncurses-dev sudo apt-get install libncurses-dev
make
make clean
sudo apt-get install srecord
make dist
rm -rf .git* rm -rf .git*
- name: Upload Artifact
uses: actions/upload-artifact@v1
with:
name: RomWBW-${{env.PKGLBL}}-Package
path: .
- name: Create Package Archive - name: Create Package Archive
run: | run: |
zip -r Package.zip .
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
zip -r RomWBW-${{env.PKGLBL}}-Package.zip .
- name: Attach Package Archive
uses: wwarthen/actions/packages/automatic-releases@built-packages
with: with:
upload_url: ${{github.event.release.upload_url}}
asset_path: Package.zip
asset_name: RomWBW-${{env.PKGLBL}}-Package.zip
asset_content_type: application/zip
repo_token: "${{ secrets.GITHUB_TOKEN }}"
draft: true
prerelease: true
title: "RomWBW Development SnapShot ${{env.PKGLBL}}"
files: |
RomWBW-${{env.PKGLBL}}-Package.zip
# - name: Upload Package Archive
# uses: AButler/upload-release-assets@v2.0.2
# with:
# repo-token: ${{ secrets.GITHUB_TOKEN }}
# files: |
# RomWBW-${{env.PKGLBL}}-Package.zip
# - name: Post SnapShot
# uses: docker://antonyurchenko/git-release:latest
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# RELEASE_NAME_PREFIX: "Development SnapShot Release "
# CHANGELOG_FILE: "none"
# with:
# args: |
# RomWBW-SnapShot-Package.zip
# - name: Post SnapShot
# uses: cb80/pubrel@latest
# with:
# replace: true
# files: |
# RomWBW-SnapShot-Package.zip
# - name: Post SnapShot
# uses: wwarthen/actions/packages/automatic-releases@built-packages
# with:
# repo_token: "${{ secrets.GITHUB_TOKEN }}"
# prerelease: true
# title: "RomWBW Development SnapShot ${{env.GITHUB_REF_SLUG}}"
# files: |
# RomWBW-SnapShot-Package.zip
# - name: Remove Older Releases
# uses: wwarthen/delete-release-action@v1.2
# with:
# release-drop: true
# release-keep-count: 0
# release-drop-tag: true
# pre-release-drop: false
# pre-release-keep-count: 0
# pre-release-drop-tag: true
# draft-drop: true
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Remove Older Releases
# uses: s00d/delete-older-releases@0.2.1
# with:
# keep_latest: 1
## delete_tag_pattern: beta # defaults to ""
# delete_type: 'release'
# delete_branch: 'main'
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

26
.gitignore

@ -20,6 +20,7 @@
Binary/**/*.mym Binary/**/*.mym
Binary/**/*.pt3 Binary/**/*.pt3
!Binary/cpnos-wbw.sys
Source/**/eeprom Source/**/eeprom
Source/Apps/Assign.com Source/Apps/Assign.com
@ -49,6 +50,9 @@ Source/Images/blankhd
Source/Prop/Spin/ParPortProp.list Source/Prop/Spin/ParPortProp.list
Source/Prop/Spin/PropIO.list Source/Prop/Spin/PropIO.list
Source/Prop/Spin/PropIO2.list Source/Prop/Spin/PropIO2.list
Source/Prop/ParPortProp.list
Source/Prop/PropIO.list
Source/Prop/PropIO2.list
Source/ZPM3/bnkbios3.spr Source/ZPM3/bnkbios3.spr
Source/ZPM3/gencpm.com Source/ZPM3/gencpm.com
Source/ZPM3/gencpm.com Source/ZPM3/gencpm.com
@ -73,24 +77,34 @@ Tools/unix/zx/zx
!Source/ver.lib !Source/ver.lib
!Source/Apps/FAT/FAT.COM !Source/Apps/FAT/FAT.COM
!Source/Apps/ZMP/zmpx.com
!Source/Apps/ZMD/zmdsubs.rel
!Source/Apps/Test/vdctest/font.asm
!Source/BPBIOS/bpbuild.com !Source/BPBIOS/bpbuild.com
!Source/BPBIOS/movp112.com !Source/BPBIOS/movp112.com
!Source/BPBIOS/*.lib
!Source/BPBIOS/Z34RCP11/cledinst.com !Source/BPBIOS/Z34RCP11/cledinst.com
!Source/BPBIOS/Z34RCP11/cledsave.com !Source/BPBIOS/Z34RCP11/cledsave.com
!Source/Fonts
!Source/Images/**/*.[Cc][Oo][Mm]
!Source/RomDsk/**/*.[Cc][Oo][Mm]
!Source/Fonts/*
!Source/Images/**
!Source/RomDsk/**
!Source/UBIOS/FSFAT.BIN !Source/UBIOS/FSFAT.BIN
!Source/UBIOS/UNA-BIOS.BIN !Source/UBIOS/UNA-BIOS.BIN
!Source/ZCCP/*.[Cc][Oo][Mm] !Source/ZCCP/*.[Cc][Oo][Mm]
!Source/ZCPR-DJ/*.[Cc][Oo][Mm] !Source/ZCPR-DJ/*.[Cc][Oo][Mm]
!Source/ZPM3/*.[Cc][Oo][Mm] !Source/ZPM3/*.[Cc][Oo][Mm]
!Source/ZSDOS/*.[Cc][Oo][Mm] !Source/ZSDOS/*.[Cc][Oo][Mm]
!Tools/cpm/bin
!Tools/unix/zx
!Tools/zx
!Source/ZRC/*.bin
!Source/ZZRC/*.bin
!Source/ZZRC/*.hex
!Tools/cpm/**
!Tools/unix/zx/*
!Tools/zx/*
Source/ZPM3/gencpm.com Source/ZPM3/gencpm.com
Source/ZPM3/startzpm.com Source/ZPM3/startzpm.com
Source/ZPM3/zccp.com Source/ZPM3/zccp.com
Source/ZPM3/zpmldr.com Source/ZPM3/zpmldr.com
Source/ZPM3/genbnk.dat
Source/ZSDOS/zsdos.err

6
Binary/Apps/Clean.cmd

@ -2,5 +2,11 @@
setlocal setlocal
if exist *.com del *.com if exist *.com del *.com
if exist *.ovr del *.ovr
if exist *.doc del *.doc
if exist *.hlp del *.hlp
if exist Tunes\*.pt? del Tunes\*.pt? if exist Tunes\*.pt? del Tunes\*.pt?
if exist Tunes\*.mym del Tunes\*.mym if exist Tunes\*.mym del Tunes\*.mym
if exist Tunes\*.vgm del Tunes\*.vgm
pushd Test && call Clean || exit /b 1 & popd

7
Binary/Apps/Makefile

@ -1,10 +1,11 @@
TOOLS = ../../Tools TOOLS = ../../Tools
MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.com Tunes/*)
MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.com)
SUBDIRS = Test
include $(TOOLS)/Makefile.inc include $(TOOLS)/Makefile.inc
all:: all::
mkdir -p Tunes mkdir -p Tunes
clobber::
rm -f *.bin *.com *.img *.rom *.pdf *.log *.eeprom *.COM *.BIN Tunes/*.mym Tunes/*.pt?
clean::
@rm -f *.bin *.com *.img *.rom *.pdf *.log *.eeprom *.ovr *.hlp *.doc *.COM *.BIN Tunes/*.mym Tunes/*.pt? Tunes/*.vgm

9
Binary/Apps/ReadMe.txt

@ -11,4 +11,11 @@ are specific to RomWBW. The source for these applications is found
in the Source\Apps directory of the distribution. in the Source\Apps directory of the distribution.
The Tunes subdirectory contains some sample ProTracker and MYM sound The Tunes subdirectory contains some sample ProTracker and MYM sound
files that can be played by the TUNE application.
files that can be played by the TUNE application.
All of these files are already included in the pre-built boot disk
images. They are also included on the ROM disk except for
FAT.COM, TUNE.COM, and the sample tune files in the Tunes directory.
If you upgrade your ROM to a new version, you should also copy
these files over to any hard disk images you are using.

4
Binary/Apps/Test/Clean.cmd

@ -0,0 +1,4 @@
@echo off
setlocal
if exist *.com del *.com

7
Binary/Apps/Test/Makefile

@ -0,0 +1,7 @@
TOOLS = ../../../Tools
MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.com)
include $(TOOLS)/Makefile.inc
clean::
@rm -f *.com

16
Binary/Apps/Test/ReadMe.txt

@ -0,0 +1,16 @@
***********************************************************************
*** ***
*** R o m W B W ***
*** ***
*** Z80/Z180 System Software ***
*** ***
***********************************************************************
This directory contains various hardware test application files that
are specific to RomWBW. The source for these applications is found
in the Source\Apps\Test directory of the distribution.
These files are included on the pre-built disk images in user area 2.
N.B., these files may be specific to certain hardware. They should
be used as directred by the instructions for your specific hardware.

2
Binary/Apps/Tunes/ReadMe.txt

@ -7,4 +7,4 @@
*********************************************************************** ***********************************************************************
This directory contains some sample ProTracker and MYM sound This directory contains some sample ProTracker and MYM sound
files that can be played by the TUNE application.
files that can be played by the TUNE or VGMPLAY application.

11
Binary/CPM3/Clean.cmd

@ -0,0 +1,11 @@
@echo off
setlocal
if exist *.spr del *.spr
if exist *.com del *.com
if exist *.sys del *.sys
if exist *.pat del *.pat
if exist *.dat del *.dat
if exist *.1st del *.1st
if exist *.spr del *.spr
if exist *.pat del *.pat

7
Binary/CPM3/Makefile

@ -0,0 +1,7 @@
TOOLS = ../../Tools
MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.spr)
include $(TOOLS)/Makefile.inc
clean::
@rm -f *.spr *.com *.sys *.dat cpm3fix.pat readme.1st

17
Binary/CPM3/ReadMe.txt

@ -0,0 +1,17 @@
***********************************************************************
*** ***
*** R o m W B W ***
*** ***
*** Z80/Z180 System Software ***
*** ***
***********************************************************************
This directory contains the CP/M 3 system files for the RomWBW CP/M 3
adaptation. All of these files are already included on the CP/M 3
boot disk images. However if you are creating a CP/M 3 boot disk
manually, you should copy all of these files to the boot disk.
These files should also be copied to any CP/M 3 boot disks on your
system when you upgrade your ROM firmware. Some of these files
*must* match the version of the RomWBW firmware you are using for
proper operation of your system.

8
Binary/Clean.cmd

@ -2,11 +2,15 @@
setlocal setlocal
if exist *.bin del *.bin if exist *.bin del *.bin
if exist *.dat del *.dat
if exist *.com del *.com if exist *.com del *.com
if exist *.img del *.img if exist *.img del *.img
if exist *.rom del *.rom if exist *.rom del *.rom
if exist *.hex del *.hex
if exist *.upd del *.upd
if exist *.pdf del *.pdf if exist *.pdf del *.pdf
if exist *.log del *.log
if exist *.eeprom del *.eeprom if exist *.eeprom del *.eeprom
setlocal & cd Apps && call Clean || exit /b 1 & endlocal
pushd Apps && call Clean || exit /b 1 & popd
pushd CPM3 && call Clean || exit /b 1 & popd
pushd ZPM3 && call Clean || exit /b 1 & popd

167
Binary/DiskList.txt

@ -1,167 +0,0 @@
***********************************************************************
*** ***
*** R o m W B W ***
*** ***
*** Z80/Z180 System Software ***
*** ***
***********************************************************************
This directory ("Binary") is part of the RomWBW System Software
distribution archive. Refer to the ReadMe.txt file in this
directory for more information on the overall contents of the
directory.
RomWBW includes a set of disk images that are ready to copy onto
a floppy or hard/CF/SD disk. You can use your modern computer
(Windows/Linux/Mac) to copy the disk image file onto your disk
media. The disk media will then be ready to use in your RomWBW
System.
A description of the disk images is provided later in this file.
For more information on the creatioin of these images including
instructions for customizing them or creating your own, refer to
the ReadMe.txt file in the Source\Images directory.
Installing Images
-----------------
The following instructions apply to Windows computers. Alternatively,
you can use the "dd" command on Linux or Mac.
First of all, a MAJOR WARNING!!!! The tools described below are
quite capable of obliterating your running Windows system drive. Use
with extreme caution and make sure you have backups.
To install a floppy image on floppy media, you can use the tool
called RaWriteWin. This tool is included in the Tools directory of
the distribution. This tool will write your floppy image (fd_xxx.img)
to a floppy disk using a raw block transfer. The tool is GUI based
and it's operation is self explanatory.
To install a hard disk image on a CF card or SD card, you must have
the appropriate media card slot on your computer. If you do, you can
use the tool called Win32DiskImager. This tool is also included in
the Tools directory of the distribution. It will write your
hard disk image (hd_xxx.img) to the designated media card. This tool
is also GUI based and self explanatory.
The use of the SIMH emulator is outside of the scope of this document.
However, if you use SIMH, you will find that you can attach the hard
disk images to the emulator with lines such as the following in your
SIMH configuration file:
| attach hdsk0 hd_cpm22.img
| set hdsk0 format=HDSK
| set hdsk0 geom=T:2048/N:256/S:512
| set hdsk0 wrtenb
Making Disk Images Bootable
---------------------------
The Operating System disk images below are ready to boot by the
RomWBW Boot Loader. However, if you update your RomWBW ROM, then
you should also update the system tracks of your bootable disk
images. You would use SYSCOPY to do this. SYSCOPY can also be
used to make a disk bootable if it is not already bootable.
You would use a command like the following to make drive C bootable:
| B>SYSCOPY C:=CPM.SYS
The system file to use depends on the operating system you are trying
to boot from the slice you are initializing with SYSCOPY:
CP/M 2.2 - cpm.sys
ZSDOS 1.1 - zsys.sys
CP/M 3 - cpmldr.sys
ZPM3 - cpmldr.sys
Slices
------
A RomWBW CP/M filesystem is fixed at 8MB. This is because it is the
largest size filesystem supported by all common CP/M variants. Since
all modern hard disks (including SD Cards and CF Cards) are much
larger than 8MB, RomWBW supports the concept of "slices". This
simply means that you can concatenate multiple CP/M filesystems (up
to 256 of them) on a single physical hard disk and RomWBW will allow
you to assign drive letters to them and treat them as multiple
independent CP/M drives.
With the exception of the hd_combo image, each of the disk images
includes a single CP/M file system (i.e., a single slice). However,
you can easily create a multi-slice disk image by merely concatenating
multiple images together. For example, if you wanted to create a 2
slice disk image that has ZSDOS in the first slice and Wordstar in
the second slice, you could use the following command from a Windows
command prompt:
| C:\RomWBW\Binary>copy /b hd_zsdos.img + hd_ws.img hd_multi.img
You can now write hd_multi.img onto your SD or CF Card and you will
have ZSDOS in the first slice and Wordstar in the second slice.
The hd_combo disk image is an example of this. It contains several
slices in one image file. The contents of this special disk image
are described below.
The concept of slices applies ONLY to hard disks. Floppy disks are
not large enough to support multiple slices.
Disk Image Contents
-------------------
What follows is a brief description of the contents of the
disk images automatically provided in the RomWBW distribution.
Note that all of the OS images include the RomWBW custom
support apps.
cpm22 - DRI CP/M 2.2 (Bootable Floppy and Hard Disk)
Standard DRI CP/M 2.2 distribution files along with a few commonly
used utilities.
zsdos - ZCPR1 + ZSDOS 1.1 (Bootable Floppy and Hard Disk)
Contains ZCPR1 and ZSDOS 1.1. This is roughly equivalent to the
ROM boot contents, but provides a full set of the applications
and related files that would not all fit on the ROM drive.
nzcom - NZCOM (Bootable Floppy and Hard Disk)
Standard NZCOM distribution. Note that you will need to run the
NZCOM setup before this will run properly. You will need
to refer to the NZCOM documentation.
cpm3 - DRI CP/M3 (Bootable Floppy and Hard Disk)
Standard DRI CP/M 3 adaptation for RomWBW that is ready to run.
It can be started by running CPMLDR.
zpm3 - ZPM3 (Bootable Floppy and Hard Disk)
Simeon Cran's ZCPR 3 compatible OS for CP/M 3 adapted for RomWBW and
ready to run. It can be started by running CPMLDR (which seems
wrong, but ZPMLDR is somewhat broken).
ws4 - WordStar 4 (Floppy and Hard Disk)
Micropro Wordstar 4 full distribution. This image is not bootable
and is intended to be added as an additional slice to an OS image.
bp - BPBIOS (Hard Disk only)
Adaptation of BPBIOS for RomWBW. This is NOT complete and NOT
useable in it's current state.
combo - Multi-Boot Combination (Bootable Hard Disk)
A pre-created combo image that contains the following slices. The
slices are identical to the individual images listed above.
Slice 0: cpm22 (bootable)
Slice 1: zsdos (bootable)
Slice 2: nzcom (bootable)
Slice 3: cpm3 (bootable)
Slice 4: zpm3 (bootable)
Slice 5: ws4 (not bootable)

6
Binary/Makefile

@ -1,8 +1,8 @@
TOOLS = ../Tools TOOLS = ../Tools
MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.img *.rom *.com *.eeprom) MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.img *.rom *.com *.eeprom)
SUBDIRS = Apps
SUBDIRS = Apps CPM3 ZPM3
include $(TOOLS)/Makefile.inc include $(TOOLS)/Makefile.inc
clobber::
rm -f *.bin *.com *.img *.rom *.pdf *.log *.eeprom
clean::
@rm -f *.bin *.com *.img *.rom *.upd *.hex *.pdf *.log *.eeprom *.dat

35
Binary/ReadMe.txt

@ -42,6 +42,15 @@ MK4_custom.rom will be added to this directory.
Documentation of the pre-built ROM Images is contained in the Documentation of the pre-built ROM Images is contained in the
RomList.txt file in this directory. RomList.txt file in this directory.
ROM Firmware Update Images (<plt>_<cfg>.upd)
-------------------------------------
The files with a ".upd" extension are binary images identical to the
.rom files, but they only have the first 128K bytes. The first 128K
is the system image without the ROM disk contents. These files can be
used to update the system image without modifying the ROM disk
contents. Refer to the RomWBW User Guide for more information.
ROM Executable Images (<plt>_<cfg>.com) ROM Executable Images (<plt>_<cfg>.com)
--------------------------------------- ---------------------------------------
@ -66,8 +75,8 @@ The VDU video board requires a dedicated onboard ROM containing the
font data. The "vdu.rom" file contains the binary data to program font data. The "vdu.rom" file contains the binary data to program
onto that chip. onto that chip.
Disk Images (fd_*.img, hd_*.img)
------------------------------
Disk Images (fd_*.img, hd_*.img, psys.img)
------------------------------------------
RomWBW includes a mechanism for generating floppy disk and hard disk RomWBW includes a mechanism for generating floppy disk and hard disk
binary images that are ready to copy directly to a floppy, hard disk, binary images that are ready to copy directly to a floppy, hard disk,
@ -87,10 +96,18 @@ RawWriteWin (as long as you have access to a floppy drive on your
Windows computer). The resulting floppy disks will be usable on any Windows computer). The resulting floppy disks will be usable on any
RomWBW-based system with floppy drive(s). RomWBW-based system with floppy drive(s).
Likewise, the hd_*.img files are hard disk images. Each file is
intended to be copied to the start of any type of hard disk media
(typically a CF Card or SD Card). The resulting media will be usable
on any RomWBW-based system that accepts the corresponding media type.
Likewise, the hd512_*.img and hd1k_*.img files are hard disk images.
Each file is intended to be copied to the start of any type of hard
disk media (typically a CF Card or SD Card). The resulting media will
be usable on any RomWBW-based system that accepts the corresponding
media type.
NOTE: The hd512_*.img files are equivalent to the hd_*.img
files in previous distributions. The hd1k_*.img files
contained a revised file system format that increases the
maximum number of CP/M directory entries from 512 to 1024.
Refer to the ReadMe.txt in the Source/Images directory
for details.
Documentation of the pre-built disk images is contained in the Documentation of the pre-built disk images is contained in the
DiskList.txt file in this directory. DiskList.txt file in this directory.
@ -100,6 +117,12 @@ the BuildImages.cmd script in the Source directory. Additional
information on how to generate custom disk images is found in the information on how to generate custom disk images is found in the
Source\Images ReadMe.txt file. Source\Images ReadMe.txt file.
The psys.img file contains a full implementation of the UCSD p-System
for the Z80 running under RomWBW. This image file must be placed on
disk media by itself (not appended or concatenated with hd*.img files.
Refer to the Source/pSys/ReadMe.txt file for more information on the
p-System implementation.
Propeller ROM Images (*.eeprom) Propeller ROM Images (*.eeprom)
------------------------------- -------------------------------

218
Binary/RomList.txt

@ -1,218 +0,0 @@
***********************************************************************
*** ***
*** R o m W B W ***
*** ***
*** Z80/Z180 System Software ***
*** ***
***********************************************************************
This directory ("Binary") is part of the RomWBW System Software
distribution archive. Refer to the ReadMe.txt file in this
directory for more information on the overall contents of the
directory.
When distributed, RomWBW contains a set of pre-built ROM images that
are ready to program onto the EEPROM of any of the Z80/Z180 based
RetroBrew Computers CPU boards. Additionally, any custom built ROM
images will be placed in this directory.
All of the pre-built ROM images are 512KB. This size is compatible
with all of the Z80/Z180 systems. Some systems can accept different
size ROM images. Creating alternative sizes requires a custom ROM
build (see ReadMe.txt in the Source directory).
It is critical that the right ROM Imgae be selected for the target
platform being used. The table below indicates the correct ROM
image to use for each platform:
SBC V1/V2 SBC_std.rom
SBC SimH SBC_simh.rom
Zeta V1 ZETA_std.rom
Zeta V2 ZETA2_std.rom
N8 N8_std.rom
Mark IV MK4_std.rom
RC2014 w/ Z80 RCZ80_std.rom
RC2014 w/ Z180 RCZ180_nat.rom (native Z180 memory addressing)
RC2014 w/ Z180 RCZ180_ext.rom (external 512K RAM/ROM module)
SC-series SC126, SC130
Easy Z80 EZZ180_std.rom
Dyno DYNO_std.rom
You will find there is one additional ROM image called
"UNA_std.rom". This ROM image is an UNA-based RomWBW ROM image. As
such, this ROM image can be used on any Z80/Z180 platform supported
by John Coffman's UNA BIOS. Refer to RetroBrew Computers Wiki for
more information on UNA hardware support.
For each of the ROM Images (".rom"), there are corresponding files
with the extensions of ".com" and ".img". The .com variant can be
copied to a functional RomWBW-based system and executed like a
normal application under CP/M or Z-System. This will load the new
ROM on-the-fly. It is an excellent way to test a ROM Image before
actually burning it. Similarly, the .img files can be loaded using
the UNA FAT loader for testing.
WARNING: In a few cases the .com file is too big to load. If you get
a message like "Full" or "BAD LOAD" when trying to load one of the
.com files, it is too big. In these cases, you will not be able to
test the ROM prior to programming it.
All of the standard ROM Images are configured for:
- 512KB ROM Disk
- 512KB RAM Disk
- 38.4Kbps baud serial console (*)
- Auto-discovery of all serial ports
* RC2014 and Stephen Cousins' kits run at 115,200Kbps baud
All hard disk type devices (IDE, PPIDE, CF Card, SD Card) will be
automatically assigned two drive letters per device. The drive
letters will refer to the first 2 slices of the device. The ASSIGN
command can be used to display and reassign drives to disk devices
and slices as desired.
Standard ROM Image Notes
------------------------
The standard ROM images will detect and install support for certain
devices and peripherals that are on-board or frequently used with
each platform as documented below. If the device or peripheral is
not detected at boot, the ROM will simply bypass support
appropriately.
SBC (SBC_std.rom):
- CPU speed is detected at startup
- Console on onboard UART serial port at 38400 baud
- Includes support for PPIDE/CF Card(s) connected to on-board
parallel port.
- Includes support for CVDU and VGA3 boards. If detected at
startup, support for video and keyboard is installed
including VT-100/ANSI terminal emulation.
- Auto-detects PropIO or PropIO V2 and installs associated
video, keyboard and SD Card support if present.
- If PropIO, PropIO V2, CVDU, or VGA hardware is detected,
initial console output is determined by JP2. If JP2 is
shorted, console will go to on-board serial port, if JP2
is open, console will go to the detected video and keyboard
ports.
- SBC V1 has a known race condition in the bank switching
circuit which is likely to cause system instability. SBC
V2 does not have this issue.
SBC (SBC_simh.rom):
- SBC variant customized to run under SimH
- Implments two emulated SimH hard disk images
- Uses SimH RTC
ZETA (ZETA_std.rom):
- CPU speed is detected at startup
- Console on onboard UART serial port at 38400 baud
- Includes support for on-board floppy disk controller and
two attached floppy disks.
- Auto-detects ParPortProp and includes support for it if it
is attached.
- If ParPortProp is installed, initial console output is
determined by JP1. If JP1 is shorted, console will go to
on-board serial port, if JP1 is open, console will go to
ParPortProp video and keyboard ports.
ZETA2 (ZETA2_std.rom):
- CPU speed is detected at startup
- Console on onboard UART serial port at 38400 baud
- Includes support for on-board floppy disk controller and
two attached floppy disks.
- Auto-detects ParPortProp and includes support for it if it
is attached.
- Uses CTC to generate periodic timer interrupts.
- If ParPortProp is installed, initial console output is
determined by JP1. If JP1 is shorted, console will go to
on-board serial port, if JP1 is open, console will go to
ParPortProp video and keyboard ports.
N8 (N8_std.rom):
- CPU speed is detected at startup
- Console on Z180 onboard primary ASCI serial port at 38400 baud
- Includes support for on-board floppy disk controller and
two attached floppy disks.
- Includes support for on-board TMS9918 video and keyboard
including VT-100/ANSI terminal emulation.
- Includes support for on-board SD Card as hard disk and
assumes a production level N8 board (date code >= 2312).
MK4 (MK4_std.rom):
- CPU speed is detected at startup
- Console on Z180 onboard primary ASCI serial port at 38400 baud
- Includes support for on-board IDE port (CF Card via adapter).
- Includes support for on-board SD Card port.
- Auto-detects PropIO or PropIO V2 and installs associated
video, keyboard and SD Card support if present.
- Includes support for CVDU and VGA3 boards. If detected at
startup, support for video and keyboard is installed
including VT-100/ANSI terminal emulation.
RCZ80 (RCZ80_std.rom):
- Assumes CPU oscillator of 7.3728 MHz
- Requires 512K RAM/ROM module
- Auto detects Serial I/O Module (ACIA) and Dual Serial
Module (SIO/2). Either one may be used.
- Console on whichever serial module is installed,
but will use the SIO/2 if both are installed. Baud
rate is determined by hardware, but normally 115200.
- Includes support for RC2014 Compact Flash Module
- Support for RC2014 PPIDE Module may be enabled in config
- Support for Scott Baker SIO board may be enabled in config
- Support for Scott Baker floppy controllers (SMC & WDC) may
be enabled in config
RCZ80 w/ KIO (RCZ80_kio.rom):
- Assumes CPU oscillator of 7.3728 MHz
- Requires 512K RAM/ROM module
- Requires KIO module
- Console on KIO primary serial port at 115200 baud
- Includes support for RC2014 Compact Flash Module
- Includes support for RC2014 PPIDE Module
- Support for Scott Baker SIO board may be enabled in config
- Support for Scott Baker floppy controllers (SMC & WDC) may
be enabled in config
RCZ180 (RCZ180_nat.rom & RCZ180_ext.rom):
- Assumes CPU oscillator of 18.432 MHz
- Console on Z180 onboard primary ASCI serial port at 115200 baud
- Includes support for RC2014 Compact Flash Module
- Includes support for RC2014 PPIDE Module
- Support for alternative serial modules may be enabled in config
- Support for Scott Baker floppy controllers (SMC & WDC) may
be enabled in config
- You must pick the _nat or _ext variant depending on which
memory module you are using:
- RCZ180_nat.rom uses the built-in Z180 memory manager
for use with memory modules allow direct physical
addressing of memory, such as the SC119
- RCZ180_ext.rom uses external bank management to access
memory, such as the 512K RAM/ROM module.
SCZ180 (SCZ180_126.rom, SCZ180_130.rom, SCZ180_131.rom):
- Assumes CPU oscillator of 18.432 MHz
- Console on Z180 onboard primary ASCI serial port at 115200 baud
- Includes support for RC2014 Compact Flash Module
- Includes support for RC2014 PPIDE Module
- Support for alternative serial modules may be enabled in config
- Support for Scott Baker floppy controllers (SMC & WDC) may
be enabled in config
- The 3 different variants of SCZ180 are provided to match the
3 corresponding systems (SC126, SC130, and SC131) designed by
Stephen Cousins.
EZZ80 (EZZ80_std.rom):
- Assumes CPU oscillator of 10.000 MHz
- Console on primary SIO serial port at 115200 baud
- Includes support for on-board SIO
- Includes support for RC2014 Compact Flash Module
- Includes support for RC2014 PPIDE Module
DYNO (DYNO_std.rom):
- Assumes CPU oscillator of 18.432 MHz
- Console on Z180 onboard serial ports at 38400 baud
- Includes support for BQ4842 RTC
- Includes support for onboard PPIDE
- Support for Dyno floppy controllers may be enabled in config

10
Binary/ZPM3/Clean.cmd

@ -0,0 +1,10 @@
@echo off
setlocal
if exist *.spr del *.spr
if exist *.com del *.com
if exist *.sys del *.sys
if exist *.pat del *.pat
if exist *.dat del *.dat
if exist *.zpm del *.zpm
if exist *.spr del *.spr

7
Binary/ZPM3/Makefile

@ -0,0 +1,7 @@
TOOLS = ../../Tools
MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.spr)
include $(TOOLS)/Makefile.inc
clean::
@rm -f *.spr *.com *.sys *.dat *.zpm

17
Binary/ZPM3/ReadMe.txt

@ -0,0 +1,17 @@
***********************************************************************
*** ***
*** R o m W B W ***
*** ***
*** Z80/Z180 System Software ***
*** ***
***********************************************************************
This directory contains the ZPM3 system files for the RomWBW ZPM3
adaptation. All of these files are already included on the ZPM3
boot disk images. However if you are creating a CP/M 3 boot disk
manually, you should copy all of these files to the boot disk.
These files should also be copied to any ZPM3 boot disks on your
system when you upgrade your ROM firmware. Some of these files
*must* match the version of the RomWBW firmware you are using for
proper operation of your system.

BIN
Binary/cpnos-wbw.sys

Binary file not shown.

6
Build.cmd

@ -0,0 +1,6 @@
@echo off
setlocal
pushd Source && call Build %* || exit /b & popd
if "%*" == "" pause

5
Clean.cmd

@ -0,0 +1,5 @@
@echo off
setlocal
pushd Binary && call Clean || exit /b 1 & popd
pushd Source && call Clean || exit /b 1 & popd

131
Doc/ChangeLog.txt

@ -1,3 +1,100 @@
Version 3.2
-----------
- WBW: Version bump for release
Version 3.1.1
-------------
- WBW: Version bumped due to pervasive changes
- WBW: Preliminary hard disk partition support (backward compatible)
- WBW: Change Propeller VGA signal timings to 60Hz refresh
- WBW: Enhanced SYSTEM RESET function to allow a warm start back to boot loader
- C?O: Add DUART driver
- WBW: Early Z280 support (requires 512K RAM/ROM board)
- HCS: ZRC memory manager support
- S?K: Support for Tiny Z80 by Sergey
- E?B: Support for v6 YM/AY sound card
- C?M: Support for RCBus bus PropIO V2
- W?S: Updated FLASH software to v1.3.4
- PMS: Preliminary support for writing to FLASH ROMs
- PMS: Creation of process to update ROM system area w/o updating ROM disk contents
- PMS: Added "updater.asm" which allows uploading and updating ROM in one step
- WBW: Support for Z280 w/ native memory and interrupt mode 3
- WBW: Support for Z280 UART (interrupt driven only in interrupt mode 3)
- WBW: Add support Z80-512K (watchdog and LED)
- WBW: Add support for ZZ80MB address map
- PLS: Add support for Z180 invalid opcode trap
- WBW: Add support for ZZRCC
- WBW: Allow selection of RAM/ROM disk individually in build
- WBW: Support 256KB ROM size
- WBW: CP/M 3 RTC support is now complete (reads and writes RTC date/time)
- WBW: Add config to allow swapping logical order of MT011 SPI ports
- WBW: COPY.COM updated from v1.72 -> v1.73 throughout distribution
- D?M: CP/NET for CP/M 2.2 and CP/M 3 (requires MT011)
- D?M: SD driver fixes for MT011
- J?C: Added FIND application from Jay Cotton
- PMS: Preliminary support for I2C-based DS1307 clock
- WBW: FD driver auto hardware detect (thanks Alan Cox)
- D?N: Added support for TMS V9958 VDU
- D?N: Added support for MSX keyboard
- D?N: Added support for RP5C01 RTC
- L?N: Slightly enhanced ZCPRD&J w/ a couple bug fixes
- L?N: UNZIPZ4 which handles most modern ZIP file compression algorithms
- AJL: Preliminary support for MBC systems
- WBW: Added preliminary support for DSKYng
- WBW: Elevated MBC to a platform
- WBW: Added support for MBC user LEDs
- PMS: Early DMA support
- W?S: Updated FLASH software to v1.3.5 (supports 128KB A29010B, 512KB A29040B)
- DDW: Support for DSKYng capabitlities
- WBW: Added Phil Summers' ROM Updater into ROM Loader
- AJL: Added ramtest app (requires SBC and MBC for now)
- L?N: Provided SCOPY, XSUB01, and EX applications
- WBW: Added support for MBC FDC to FDU application
- WBW: Added support for MBC FDC to HBIOS
- WBW: Refactored make process
- WBW: Added ROM verification to boot process
- WBW: Added Z80 instruction test apps to user area 5 in CP/M & ZSDOS
- WBW: Add support for LINC sound card
- WBW: Add interrupt receive support to UART driver
- PMS: Add XModem transfer within Debug Monitor
- PMS & AJL: Add DMAMON test application
- PMS: Add ZMP adaptation
- LWN: Substantial BPBIOS cleanup
- AJL: Add ZMD adaptation
- D?T: Substantial update to TastyBasic incuding a .COM executable
- PMS: Added VGM audio file player
- WBW: ZPMLDR and ZPM3 fixes, credit to Lars Nelson for finding ZPM3 source!
- DDW: Add support for MBC sound card
- WBW: Add support for "romless" booting
- L?N: Fixes for ZCPR-D&J (buffer overflow, default drive/user)
- J?P: Add support for DS1501 RTC
- LLS: Added a user defined mode for SD Card interfaces (not complete)
- L?N: Updated ZDE to v1.8 including time stamp preservation fixes
- D?M: Minor update to CP/NET client files, fix to CPNBOOT
- WBW: Added p-System IV.0 Z80 implementation
- WBW: Hacked SURVEY to work around bank switching crash
Version 3.1
-----------
- WBW: Refactored ROM Loader
- WBW: INTRTC periodic timer based clock
- WBW: FDISK80 updated to allow reserving up to 256 slices
- WBW: Added support dual 16C550 UART on RCBus platform
- WBW: Made .com images smaller (contain only Z-System now)
- WBW: Support automatic clock hardware detection and fallback
- WBW: Support use of CTC for SIO baud rate divisors
- WBW: Updated IDE and PPIDE drivers to improve old CF Card compatibility
- WBW: Support TIMER mode in CTC driver
- DEN: Added sound driver support
- DEN: Added SN76489 sound chip driver
- M?O: RomWBW Disk Catalog document
- DEN: Updated TMS to optionally trigger SYSTIMER interrupt (TMSTIMENABLE)
- J?M: Updated KERMIT applications with VT100 terminal support
- A?C: Added support for EPFDC
- PMS: Added AY driver with new sound API support
- DEN: Allow immediate autoboot startup
- DEN: Support for floppy device count parameter
Version 3.0.1 Version 3.0.1
------------- -------------
- WBW: Increase XModem timeout waiting for host to start sending - WBW: Increase XModem timeout waiting for host to start sending
@ -20,8 +117,8 @@ Version 2.9.2
- WBW: Support two SIO modules w/ auto-detection - WBW: Support two SIO modules w/ auto-detection
- PMS: Support ECB USB-FIFO board - PMS: Support ECB USB-FIFO board
- WBW: Fixed ASSIGN issue with incorrect DPB selection - WBW: Fixed ASSIGN issue with incorrect DPB selection
- WBW: Add RC2014 Z180 AY sound support to TUNE app
- WBW: Add RC2014 AY sound support to AY driver
- WBW: Add RCBus Z180 AY sound support to TUNE app
- WBW: Add RCBus AY sound support to AY driver
- WBW: Add SC126 platform - WBW: Add SC126 platform
- WBW: Config files cleanup - WBW: Config files cleanup
- WBW: Add interrupt support to ASCI driver - WBW: Add interrupt support to ASCI driver
@ -40,7 +137,7 @@ Version 2.9.2
- PMS: Add sound support to NASCOM BASIC - PMS: Add sound support to NASCOM BASIC
- WBW: Updated FAT to add MD and FORMAT commands - WBW: Updated FAT to add MD and FORMAT commands
- WBW: Add CP/M 3 (experimental) - WBW: Add CP/M 3 (experimental)
- M?T: Support Shift register SPI WIZNET for RC2014
- M?T: Support Shift register SPI WIZNET for RCBus
- PLS: Added seconds register in HBIOS - PLS: Added seconds register in HBIOS
- WBW: More flexible table-driven config in TUNE.COM - WBW: More flexible table-driven config in TUNE.COM
- PMS: Added timer support for Zilog Peripherals ECB Board - PMS: Added timer support for Zilog Peripherals ECB Board
@ -68,7 +165,7 @@ Version 2.9.2
Version 2.9.1 Version 2.9.1
------------- -------------
- E?B: Added support for RC2014 RTC
- E?B: Added support for RCBus RTC
- WBW: Converted PTXPLAY to TUNE (now plays PT2/PT3/MYM sounds files) - WBW: Converted PTXPLAY to TUNE (now plays PT2/PT3/MYM sounds files)
- WBW: Updated Win32DiskImager to v1.0 - WBW: Updated Win32DiskImager to v1.0
- WBW: Implemented character attributes on Propeller based consoles - WBW: Implemented character attributes on Propeller based consoles
@ -78,7 +175,7 @@ Version 2.9.1
- WBW: Update default IOBYTE so that LST:=LPT: by default - WBW: Update default IOBYTE so that LST:=LPT: by default
- WBW: Fixed missing drive/head setup for writes in PPIDE - WBW: Fixed missing drive/head setup for writes in PPIDE
- WBW: Fixed XModem HBIOS console driver for file send operations - WBW: Fixed XModem HBIOS console driver for file send operations
- WBW: Preliminary support for RC180 platform (Z180 module in RC2014)
- WBW: Preliminary support for RC180 platform (Z180 module in RCBus)
- WBW: Added NZCOM distribution files to third slice of hard disk image - WBW: Added NZCOM distribution files to third slice of hard disk image
- WBW: Fixed getnum32 bug in MODE command (found by Phil Summers) - WBW: Fixed getnum32 bug in MODE command (found by Phil Summers)
- PMS: Added serial support for Zilog Peripherals Baord - PMS: Added serial support for Zilog Peripherals Baord
@ -90,32 +187,32 @@ Version 2.9.1
- PMS: Added Forth, Nascom BASIC, and Tasty BASIC to ROM - PMS: Added Forth, Nascom BASIC, and Tasty BASIC to ROM
- PMS: Refactored ROM Loader to support more ROM images, now table driven - PMS: Refactored ROM Loader to support more ROM images, now table driven
- WBW: Refactored DSKY code - WBW: Refactored DSKY code
- SK: Initial support for Easy Z80
- S?K: Initial support for Easy Z80
- PMS: Enhance VDU driver to support alternative screen dimensions - PMS: Enhance VDU driver to support alternative screen dimensions
- WBW: DDT and DDTZ modified to use RST 30 instead of RST 38 to avoid conflicts with IM 1 interrupts - WBW: DDT and DDTZ modified to use RST 30 instead of RST 38 to avoid conflicts with IM 1 interrupts
- WBW: Added timer interrupt support for CTC under Zeta 2 and Easy Z80 - WBW: Added timer interrupt support for CTC under Zeta 2 and Easy Z80
- WBW: Support LBA style access in floppy driver - WBW: Support LBA style access in floppy driver
- WBW: Added beta version of FAT filesystem utility (copy, dir, del, ren) - WBW: Added beta version of FAT filesystem utility (copy, dir, del, ren)
- SCC: Added support for native memory addressing on Z180-based RC2014
- SCC: Added support for native memory addressing on Z180-based RCBus
- PMS: Dynamically discover and display processor type at boot - PMS: Dynamically discover and display processor type at boot
- J?L: Added German keyboard support to PPK and KBD drivers - J?L: Added German keyboard support to PPK and KBD drivers
Version 2.9.0 Version 2.9.0
------------- -------------
- WBW: Implemented multi-sector I/O in all disk drivers - WBW: Implemented multi-sector I/O in all disk drivers
- WBW: Added support for RC2014 SMB Floppy controller modules (SMC and WDC)
- WBW: Added support for RCBus SMB Floppy controller modules (SMC and WDC)
- WBW: New function dispatching for character/disk/video drivers - WBW: New function dispatching for character/disk/video drivers
- WBW: Updated FDU app to support RC2014 floppy controllers
- WBW: Updated FDU app to support RCBus floppy controllers
- WBW: Added TIMER app to display system timer value - WBW: Added TIMER app to display system timer value
- WBW: Refactored interrupt management code - WBW: Refactored interrupt management code
- WBW: Added PTXPLAY application and sample tunes - WBW: Added PTXPLAY application and sample tunes
Version 2.8.6 Version 2.8.6
------------- -------------
- WBW: Added support for RC2014 (SIO and ACIA drivers primarily)
- WBW: Added support for RCBus (SIO and ACIA drivers primarily)
- WBW: Automatically detect and run PROFILE.SUB on boot drive if it exists - WBW: Automatically detect and run PROFILE.SUB on boot drive if it exists
- WBW: Fixed Dual SD Board detection - WBW: Fixed Dual SD Board detection
- WBW: Added console support to XModem (for RC2014 primarily)
- WBW: Added console support to XModem (for RCBus primarily)
- E?B: Fixed IDE/PPIDE when used with non-CF drives - E?B: Fixed IDE/PPIDE when used with non-CF drives
- WBW: Patched SUBMIT.COM so that it always puts temp file on A: for immediate execution - WBW: Patched SUBMIT.COM so that it always puts temp file on A: for immediate execution
- WBW: Accommodate spin up time for true IDE hard disks (IDE or PPIDE) - WBW: Accommodate spin up time for true IDE hard disks (IDE or PPIDE)
@ -268,7 +365,7 @@ Version 2.0
- DWG: Entire new suite of Apps written in Aztec C - DWG: Entire new suite of Apps written in Aztec C
- DWG: BANKER.COM - displays bank identification and version information - DWG: BANKER.COM - displays bank identification and version information
- DWG: CPMNAME.COM - displays CBIOS header data and SYSCFG data, names and vaues - DWG: CPMNAME.COM - displays CBIOS header data and SYSCFG data, names and vaues
- DWG: CHARS.COM - displays ascii map as reference
- DWG: CHARS.COM - displays ascii map as reference
- DWG: CLS.COM - clears screen - DWG: CLS.COM - clears screen
- DWG: LABEL.COM - displays and changes drive labels for drives with reserved tracks - DWG: LABEL.COM - displays and changes drive labels for drives with reserved tracks
- DWG: MAP.COM - like old map command, displays drives and logical unit labels and changes LU values - DWG: MAP.COM - like old map command, displays drives and logical unit labels and changes LU values
@ -300,7 +397,7 @@ Version 1.5.1
- WBW: Added ZSDOS clock drivers (see Support\Clock) - WBW: Added ZSDOS clock drivers (see Support\Clock)
- WBW: Overhaul of ZSystem ROM Disk (see Doc\ZSystem.txt) - WBW: Overhaul of ZSystem ROM Disk (see Doc\ZSystem.txt)
- WBW: Update PropIO ANSI emulation for compatiblity with ASSIGN - WBW: Update PropIO ANSI emulation for compatiblity with ASSIGN
- DWG: Added version tags to all applications, and IDENT program to
- DWG: Added version tags to all applications, and IDENT program to
check version of utilities. check version of utilities.
- DWG: Added MULTIFMT program which prepares new media for use by - DWG: Added MULTIFMT program which prepares new media for use by
initializing the metadata and clearing the directory sectors of initializing the metadata and clearing the directory sectors of
@ -310,8 +407,8 @@ Version 1.5.1
- DWG: ANALYSE and HELLO programs removed from ROM due space concerns - DWG: ANALYSE and HELLO programs removed from ROM due space concerns
- DWG: Additional macro librarties added supporting program identification - DWG: Additional macro librarties added supporting program identification
(IDENTITY.LIB/ASM) and access to drive metadata (METADATA.LIB/ASM), (IDENTITY.LIB/ASM) and access to drive metadata (METADATA.LIB/ASM),
and realtime selection of logical units from within new application
programs (LOGICALS.LIB/ASM).
and realtime selection of logical units from within new application
programs (LOGICALS.LIB/ASM).
- DWG: Added TERM_VT52 for VDU compatbility, all apps now compliant - DWG: Added TERM_VT52 for VDU compatbility, all apps now compliant
- DGG: Contributed Linux build (see Doc\BuildLinux.txt) - DGG: Contributed Linux build (see Doc\BuildLinux.txt)
@ -339,7 +436,7 @@ Version 1.4
- DWG: Add various .SUB files used for application maintenance - DWG: Add various .SUB files used for application maintenance
- DWG: Enhanced utility building .SUB files to only contain libs utilitized - DWG: Enhanced utility building .SUB files to only contain libs utilitized
- DWG: Add BUILD.SUB to build all applications and DEVFILES.LBR - DWG: Add BUILD.SUB to build all applications and DEVFILES.LBR
- DWG: Add/update RMAC macro libraries used in Apps -
- DWG: Add/update RMAC macro libraries used in Apps -
- DWG: BIOSHDR, STDLIB, STRCPY, STRLEN, CPMBIOS, CPMBDOS, TERMINAL, HARDWARE, - DWG: BIOSHDR, STDLIB, STRCPY, STRLEN, CPMBIOS, CPMBDOS, TERMINAL, HARDWARE,
- DWG: CPMAPPL, GLOBALS, ATOI, LUBIND, APPLVERS, MEMORY(memcpy,memset), PORTAB - DWG: CPMAPPL, GLOBALS, ATOI, LUBIND, APPLVERS, MEMORY(memcpy,memset), PORTAB
- DWG: Add/Repair BIOS support for Boot Drive login during CP/M Coldstart - DWG: Add/Repair BIOS support for Boot Drive login during CP/M Coldstart
@ -358,7 +455,7 @@ Version 1.4
- DWG: Add LABEL utility to insert label into drive/slice metadata - DWG: Add LABEL utility to insert label into drive/slice metadata
- DWG: Add 16 char label field to metadata - DWG: Add 16 char label field to metadata
- DWG: ASSIGN utility displays and manipulates DPH/DPB & logical unit parameters - DWG: ASSIGN utility displays and manipulates DPH/DPB & logical unit parameters
- DWG/WBW: Collaborated on design of Logical Unit DPH enhancemnt
- DWG/WBW: Collaborated on design of Logical Unit DPH enhancemnt
- WBW: Proposed MAP utility functionality - WBW: Proposed MAP utility functionality
- WBW: Implement slice selection API for DSK devices - WBW: Implement slice selection API for DSK devices
- WBW: Record boot drive in config memory at load time - WBW: Record boot drive in config memory at load time

186
Doc/Contrib/Flash4.txt

@ -1,186 +0,0 @@
FLASH4 (c) 2014 William R Sowerbutts <will@sowerbutts.com>
http://sowerbutts.com/8bit/
= Warning =
FLASH4 has been tested and confirmed working on:
* N8VEM SBCv2
* N8VEM N8-2312
* N8VEM Mark IV SBC
* DX-Designs P112
* ZETA SBC v2
However it remains somewhat experimental. If it works for you, please let me
know. If it breaks please also let me know so I can fix it!
= Introduction =
FLASH4 is a CP/M program which can read, write and verify Flash ROM contents to
or from an image file stored on a CP/M filesystem. It is intended for in-system
programming of Flash ROM chips on Z80 and Z180 systems.
FLASH4 aims to support a range of Flash ROM chips. Ideally I would like to
support all Flash ROM chips that are in use in Z80/Z180 N8VEM machines. If
FLASH4 does not support your chip please let me know and I will try to add
support.
When writing to the Flash ROM chip, FLASH4 will only reprogram the sectors
whose contents have changed. This helps to reduce wear on the flash memory,
makes the reprogram operation faster, and reduces the risk of leaving the
system unbootable if power fails during a reprogramming operation. FLASH4
always performs a full verify operation after writing to the chip to confirm
that the correct data has been loaded.
FLASH4 is reasonably fast. Reprogramming and verifying every sector on a 512KB
SST 39F040 chip takes 21 seconds on my Mark IV SBC, versus 45 seconds to
perform the same task using a USB MiniPro TL866 EEPROM programmer under Linux
on my PC. If only a subset of sectors require reprogramming FLASH4 will be
even faster.
FLASH4 works with binary ROM image files, it does not support Intel Hex format
files. Hex files can be easily converted to or from binaries using "hex2bin" or
the "srec_cat" program from SRecord:
$ srec_cat image.hex -intel -fill 0xFF 0 0x80000 -output image.bin -binary
$ srec_cat image.bin -binary -output image.hex -intel
FLASH4 can use several different methods to access the Flash ROM chip. The best
available method is determined automatically at run time. Alternatively you may
provide a command-line option to force the use of a specific method.
The first two methods use bank switching to map sections of the ROM into the
CPU address space. FLASH4 will detect the presence of RomWBW or UNA BIOS and
use the bank switching methods they provide.
On P112 systems the P112 B/P BIOS is detected and P112 bank switching is used.
If no bank switching method can be auto-detected, and the system has a Z180
CPU, FLASH4 will use the Z180 DMA engine to access the Flash ROM chip. This
does not require any bank switching but it is slower and will not work on all
platforms.
Z180 DMA access requires the flash ROM to be linearly mapped into the lower
region of physical memory, as it is on the Mark IV SBC (for example). The
N8-2312 has additional memory mapping hardware, consequently Z180 DMA access on
the N8-2312 is NOT SUPPORTED and if forced will corrupt the contents of RAM;
use one of the supported bank switching methods instead.
Z180 DMA access requires the Z180 CPU I/O base control register configured to
locate the internal I/O addresses at 0x40 (ie ICR bits IOA7, IOA6 = 0, 1).
= Usage =
The three basic operations are:
FLASH4 WRITE filename [options]
This will rewrite the flash ROM contents from the named file. The file size
must exactly match the size of the ROM chip. After the write operation, a
verify operation will be performed automatically.
FLASH4 VERIFY filename [options]
This will read out the flash ROM contents and report if it matches the contents
of the named file. The file size must exactly match the size of the ROM chip.
FLASH4 READ filename [options]
This will read out the entire flash ROM contents and write it to the named
file.
If your ROM chip is larger than the image you wish to write, use the "/PARTIAL"
(or "/P") command line option. To avoid accidentally flashing the wrong file,
the image file must be an exact multiple of 32KB in length. The portion of the
ROM not occupied by the image file is left either unmodified or erased.
If you are using an ROM/EPROM/EEPROM chip which cannot be programmed in-system,
FLASH4 will not be able to recognise it, however the software can still
usefully READ and VERIFY the chip. Use the "/ROM" command line option to enable
"READ" or "VERIFY" mode with unrecognised chips. This mode assumes a 512K ROM
is fitted; smaller ROMs will be treated as a 512K ROM with the data repated
multiple times -- with a 256K chip the data is repeated twice, four times for a
128K chip, etc.
One of the following optional command line arguments may be specified at the
end of the command line to force FLASH4 to use a particular method to access
the flash ROM chip:
BIOS interfaces:
/ROMWBW For ROMWBW BIOS version 2.6 and later
/ROMWBWOLD For ROMWBW BIOS version 2.5 and earlier
/UNABIOS For UNA BIOS
Direct hardware interfaces:
/Z180DMA For Z180 DMA
/P112 For DX-Designs P112
/N8VEMSBC For N8VEM SBC (v1, v2), Zeta (v1) SBC
If no option is specified FLASH4 attempts to determine the best available
method automatically.
= Supported chips and features =
FLASH4 will interrogate your flash ROM chip to identify it automatically.
FLASH4 assumes that you have a single flash ROM device and it is located at the
bottom of the physical memory map.
FLASH4 does not support setting or resetting the protection bits on individual
sectors within Flash ROM devices. If your Flash ROM chip has protected sectors
you will need to unprotect them by other means before FLASH4 can erase and
reprogram them.
AT29C series chips employ an optional "software data protection" feature. This
is supported by FLASH4 and is left activated after programming the chip to
prevent accidental reprogramming of sectors.
The following chips are supported:
AT29F010
AT29F040
M29F010
M29F040
MX29F040
SST 39F010
SST 39F020
SST 39F040
AT29C512
AT29C040
AT29C010
AT29C020
The following chips are supported but have unequal sector sizes; FLASH4 will
only erase and reprogram the entire chip at once rather than its normal
sector-by-sector operation:
AT49F001NT
AT49F001N
AT49F002N
AT49F002NT
AT49F040
If you use a flash ROM chip that is not listed above please email me
(will@sowerbutts.com) and I will try to add support for it.
= Compiling =
The software is written in a mix of C and assembler. It builds using the SDCC
toolchain and the SRecord tools. A Makefile is provided to build the executable
in Linux and I imagine it can be easily modified to build in Windows.
You may need to adjust the path to the SDCC libraries in the Makefile if your
sdcc installation is not in /usr/local
= License =
FLASH4 is licensed under the The GNU General Public License version 3 (see
included "LICENSE.txt" file).
FLASH4 is provided with NO WARRANTY. In no event will the author be liable for
any damages. Use of this program is at your own risk. May cause rifts in space
and time.

BIN
Doc/Contrib/How to Make Disk Images in Linux with DD Command.pdf

Binary file not shown.

BIN
Doc/Contrib/Microsoft NASCOM BASIC.docx

Binary file not shown.

39
Doc/Contrib/PPI_Bus.txt

@ -0,0 +1,39 @@
PPI Signal PPIDE PPISD DSKY DSKYNG (PROTO) DSKYNG (FINAL)
---------- ----- ----- ----- ----- -----
PA0 <>D0 >ID0 <>D0 <>D0
PA1 <>D1 >ID1 <>D1 <>D1
PA2 <>D2 >ID2 <>D2 <>D2
PA3 <>D3 >ID3 <>D3 <>D3
PA4 <>D4 >ID4 /SHUTDOWN <>D4 <>D4
PA5 <>D5 >ID5 /DECODE <>D5 <>D5
PA6 <>D6 >ID6 HEXA/CODEB <>D6 <>D6
PA7 <>D7 >ID7 DAT_COMING <>D7 <>D7
PB0 <>D8 +<ROW5
PB1 <>D9 +<ROW4
PB2 <>D10 +<ROW3
PB3 <>D11 +<ROW2
PB4 <>D12 +<ROW1
PB5 <>D13 +<ROW0
PB6 <>D14 +
PB7 <>D15 <MISO +
PC0 >DA0 >MOSI >COL0 >A0 >A0
PC1 >DA1 >CLK >COL1 >/WR
PC2 >DA2 >COL2 >/RD
PC3 >CS0* >COL3 >CS&* >CS&*
PC4 >CS1* >/CS >CS&* >CS&*
PC5 >DIOW* >/WR
PC6 >DIOR* >/WR >/RD
PC7 >RESET* >MODE >RESET >RESET
* Inverted by adapter
+ Pullup
& Both signals must be asserted
Compatibility:
- PPISD & DSKY
- PPIDE & DSKYNG
- PPISD & DSKYNG

564
Doc/DDTZ.doc

@ -1,564 +0,0 @@
DDTZ v2.7
by C.B. Falconer
edited by George A. Havach
Introduction:
============
DDTZ v2.7 is a complete replacement for DDT, Digital Research's
famous Dynamic Debugging Tool, with improved functionality, bug
extermination, and full Z80 support. In general, DDTZ is fully
compatible with the original utility, but it has extra and
extended commands and many fewer quirks. All Z80-specific
instructions can be (dis)assembled, though in Intel rather then
Zilog format. Furthermore, DDTZ will correctly trace ('T' and 'U'
commands) both 8080 and Z80 instructions, depending on which CPU
is operating. On startup, the program announces which CPU it is
running on.
DDTZ v2.7 now handles the 64180 added opcodes. It does NOT test
for a 64180 CPU, since this cannot be done without executing
illegal Z80 instructions, which in turn will crash some
simulators. However v2.7 does not execute any 64180 instructions
internally, only in the subject program.
This issue supplies the "M" version assembled, to avoid errors
when switching between MSDOS and CPM systems. The command table
is updated accordingly. Most CPM users are also MSDOS users, but
not vice-versa.
The program is invoked by typing
ddtz<ret>
or
ddtz [d:]filespec<ret>
In the second form, DDTZ will load the specified file into
memory starting at 0100H, unless it's a .HEX file that sets its
own load address. Besides reporting the NEXT free address and
the PC (program counter) after a successful load, DDTZ also shows
the number of memory pages needed for a SAVE. Instead of having
to write all this down, just use the 'X' command at any time to
redisplay these three values for the current application.
NOTE: loading more code above the NEXT pointer revises these
values.
As in DDT, when a program is loaded above the area holding the
'A' and 'U' (and now 'W') command code, these commands are
disabled, and the extra memory is released to the user. Thus,
DDTZ can occupy as little as 3K total memory space. Unlike DDT,
however, DDTZ will not overwrite itself or the system on program
loads (except .HEX files).
At initialization, the stack pointer (SP) points to a return to
DDTZ, just like for the CCP. Thus, programs that normally return
to the CCP will be returned to DDTZ. The 'B' command
reinitializes this condition.
The intercept vector copies the BDOS version number, etc., so
an object program does not know that DDTZ is running (except
for BIOS-BDOS vector size). Thus, programs that check the version
number should execute correctly under DDTZ.
All input parameters can now be entered in any of three formats:
(1) hexadecimal (as in DDT),
(2) decimal, by adding a leading '#' character,
(3) ASCII, by enclosing between either single or double
quotes; either one or two characters are allowed.
Leading blanks in command lines and parameters are absorbed.
Either a comma or a (single) space is a valid delimiter.
Either uppercase or lowercase input is accepted.
The default command (for anything not otherwise recognizable)
is 'H'. This allows convenient calculation, along with the other
features described below. So, to convert a number, just enter
it!
As in DDT, the prompt character is '-', and the only error
message is the query ('?'), which generally kicks you back to
command mode.
New Commands (Over DDT):
=======================
NOTE: letters in parenthesis, e.g. "(U)", show the equivalent
command for DDTZM version (compatible with MSDOS debug).
@ Sets or shows (with no parameter) the internally stored
"base" value. Also used with the 'S' and 'D' commands as
an optional parameter (though without the '@') to display
memory from an arbitrary base marker (offset). When set to
zero (the default), it does not affect any screen displays.
B B)egin: resets the USER stack pointer to its initial value,
such that any program that exits by an RET will return to
DDTZ. DDTZ provides a default stack space of
approximately 24 bytes for user programs.
C C)ompare first_address,last_address,against_address: shows
all the byte differences between two memory areas, in the
format
XXXX aa YYYY bb
where XXXX and YYYY are the comparative memory addresses,
and aa and bb are the corresponding byte values. Can be
used to verify the identity of two files by first
loading them into different memory areas with the 'R'
command (see below).
W Write: stores the modified memory area to disk under the
(K) filename specified by the 'I' command, overwriting the
original file from which it was loaded (the user is queried
before doing so). By default, the image of memory from
0100H through the "NEXT" value -1 is saved. "K first_addr,
last_address" overrides this and allows writing ANY memory
area to a file. Almost a necessity for CPM 3.0 (no SAVE!).
K)eep on DDTZ
X eXamine: redisplays the "NEXT PC SAVE" report at any time.
(Q) Q)uery size on DDTZ.
S S)earch first_address, last_addr, value: searches the
(W) specified memory area for the value (a 16-bit word, not a
byte) and shows the locations of all such. Very useful for
finding CALL's or JMP's to a particular address, etc.
W)here on DDTZ
Y Y)our_option parm1,parm2,address: executes an arbitrary
routine at the specified address, with the BC and DE
registers set to parm1 and parm2, respectively.
Z Displays (but does not alter) the Z80's alternate register
set, including the index registers (disabled if running on
an 8080). On Z80's, automatically included as the last
part of the display by the 'X' command.
Based (Offset) Displays:
=======================
The 'D' and 'E' commands can use a stored base value (offset),
as set by the '@' command. The current @ value may be
overridden for a single execution of these commands by adding the
base as an extra parameter in the command line. The effect is
to add this value to the first/last address and display
accordingly. The address listing on the left becomes XXXX:YYYY,
where XXXX is the offset address and YYYY is the actual memory
address being displayed. For example, if you have a data area
located at 42B7H and wish to preserve easy access, just enter
"@42b7". Now, "d0,3f" will dump memory starting at 4237H.
Further Changes from DDT:
========================
A A)ssemble now accepts the full Z80 as well as 8080
instruction set, although it expects them in Intel rather
than Zilog format (see notes below under the 'L'
command). When in doubt, see the mnemnonic list below.
D D)isplay or D)ump will accept an optional third parameter
to set the base value for a single execution only. Format
has been cleaned up.
H H)ex_arithmetic on two values also shows their
difference in decimal. With only one value, converts to
hexadecimal, decimal, and ASCII (low-order byte only).
N N)ame now allows drive specification (d:...) and sets up
(I) the complete command line, including both FCB's (at
addresses 005CH and 006CH). The tail (stored at 0081H up)
is NOT upshifted.
I)nput on DDTZ
U U)nassemble now displays the raw hexcode, especially handy
(L) when examining non-code areas. Intel (8080 style) mnemonics
are used, so some disassembled instructions may look
strange. E.g., the Z80's 'IN B,(C)' and 'OUT (C),B' become
'INP B' and 'OUTP B', respectively; 'LD (nnnn),BC' becomes
'SBCD nnnn', 'ADD IX, BC' becomes 'DADX B', and 'JP (IX)'
becomes 'PCIX'.
L)ist on DDTZ
L L)oad now permits loading a file into memory with an
(R) offset, which is added to the default load address of
0100H. When reading in a .HEX file with a preset bias,
the 'R' command will not transfer control to an invalid
execution point. Another execution of the 'R' command will
reread the input file, e.g.:
n blah<ret>
l<ret>
...modify the code and generally mess about...
l<ret>
The original file is reloaded, and the modifications are
removed.
R)ead on DDTZ
E E)nter, like D)isplay, now accepts an optional second
(S) parameter to set the base value for a single execution
only.
S)ubstitute or S)et on DDTZ
T T)rap/trace on termination now shows the complete CPU
state. Traps and traces no longer lock up when a user RST
7 instruction is executed. Tracing of BDOS/BIOS calls is
heavily trun cated, avoiding clutter and preventing system
crashes.
NOTE: Most of the UNDOCUMENTED Z80 op-codes are handled. Others
can crash the system.
R R)egisters also shows what two-byte values the HL and SP
(X) registers are actually pointing to. On Z80's, displays the
alternate register set.
eX)amine on DDTZ
NOTE: Any use of the 'W' or 'L' command resets the system DMA
transfer address to the standard default value of 0080H.
; This is the output of DDTZ when disassembling OPTYPE.TRY
NOP LDA 06A4 MOV M,H
LXI B,06A4 DCX SP MOV M,L
STAX B INR A HLT
INX B DCR A MOV M,A
INR B MVI A,20 MOV A,B
DCR B CMC MOV A,C
MVI B,20 MOV B,B MOV A,D
RLC MOV B,C MOV A,E
EXAF MOV B,D MOV A,H
DAD B MOV B,E MOV A,L
LDAX B MOV B,H MOV A,M
DCX B MOV B,L MOV A,A
INR C MOV B,M ADD B
DCR C MOV B,A ADD C
MVI C,20 MOV C,B ADD D
RRC MOV C,C ADD E
DJNZ 0134 MOV C,D ADD H
LXI D,06A4 MOV C,E ADD L
STAX D MOV C,H ADD M
INX D MOV C,L ADD A
INR D MOV C,M ADC B
DCR D MOV C,A ADC C
MVI D,20 MOV D,B ADC D
RAL MOV D,C ADC E
JR 0134 MOV D,D ADC H
DAD D MOV D,E ADC L
LDAX D MOV D,H ADC M
DCX D MOV D,L ADC A
INR E MOV D,M SUB B
DCR E MOV D,A SUB C
MVI E,20 MOV E,B SUB D
RAR MOV E,C SUB E
JRNZ 0134 MOV E,D SUB H
LXI H,06A4 MOV E,E SUB L
SHLD 06A4 MOV E,H SUB M
INX H MOV E,L SUB A
INR H MOV E,M SBB B
DCR H MOV E,A SBB C
MVI H,20 MOV H,B SBB D
DAA MOV H,C SBB E
JRZ 0134 MOV H,D SBB H
DAD H MOV H,E SBB L
LHLD 06A4 MOV H,H SBB M
DCX H MOV H,L SBB A
INR L MOV H,M ANA B
DCR L MOV H,A ANA C
MVI L,20 MOV L,B ANA D
CMA MOV L,C ANA E
JRNC 0134 MOV L,D ANA H
LXI SP,06A4 MOV L,E ANA L
STA 06A4 MOV L,H ANA M
INX SP MOV L,L ANA A
INR M MOV L,M XRA B
DCR M MOV L,A XRA C
MVI M,20 MOV M,B XRA D
STC MOV M,C XRA E
JRC 0134 MOV M,D XRA H
DAD SP MOV M,E XRA L
XRA M JPE 06A4 SLAR M
XRA A XCHG SLAR A
ORA B CPE 06A4 SRAR B
ORA C XRI 20 SRAR C
ORA D RST 5 SRAR D
ORA E RP SRAR E
ORA H POP PSW SRAR H
ORA L JP 06A4 SRAR L
ORA M DI SRAR M
ORA A CP 06A4 SRAR A
CMP B PUSH PSW SLLR B
CMP C ORI 20 SLLR C
CMP D RST 6 SLLR D
CMP E RM SLLR E
CMP H SPHL SLLR H
CMP L JM 06A4 SLLR L
CMP M EI SLLR M
CMP A CM 06A4 SLLR A
RNZ CPI 20 SRLR B
POP B RST 7 SRLR C
JNZ 06A4 RLCR B SRLR D
JMP 06A4 RLCR C SRLR E
CNZ 06A4 RLCR D SRLR H
PUSH B RLCR E SRLR L
ADI 20 RLCR H SRLR M
RST 0 RLCR L SRLR A
RZ RLCR M BIT 0,B
RET RLCR A BIT 0,C
JZ 06A4 RRCR B BIT 0,D
CZ 06A4 RRCR C BIT 0,E
CALL 06A4 RRCR D BIT 0,H
ACI 20 RRCR E BIT 0,L
RST 1 RRCR H BIT 0,M
RNC RRCR L BIT 0,A
POP D RRCR M BIT 1,B
JNC 06A4 RRCR A BIT 1,C
OUT 20 RALR B BIT 1,D
CNC 06A4 RALR C BIT 1,E
PUSH D RALR D BIT 1,H
SUI 20 RALR E BIT 1,L
RST 2 RALR H BIT 1,M
RC RALR L BIT 1,A
EXX RALR M BIT 2,B
JC 06A4 RALR A BIT 2,C
IN 20 RARR B BIT 2,D
CC 06A4 RARR C BIT 2,E
SBI 20 RARR D BIT 2,H
RST 3 RARR E BIT 2,L
RPO RARR H BIT 2,M
POP H RARR L BIT 2,A
JPO 06A4 RARR M BIT 3,B
XTHL RARR A BIT 3,C
CPO 06A4 SLAR B BIT 3,D
PUSH H SLAR C BIT 3,E
ANI 20 SLAR D BIT 3,H
RST 4 SLAR E BIT 3,L
RPE SLAR H BIT 3,M
PCHL SLAR L BIT 3,A
BIT 4,B RES 3,D SET 2,H
BIT 4,C RES 3,E SET 2,L
BIT 4,D RES 3,H SET 2,M
BIT 4,E RES 3,L SET 2,A
BIT 4,H RES 3,M SET 3,B
BIT 4,L RES 3,A SET 3,C
BIT 4,M RES 4,B SET 3,D
BIT 4,A RES 4,C SET 3,E
BIT 5,B RES 4,D SET 3,H
BIT 5,C RES 4,E SET 3,L
BIT 5,D RES 4,H SET 3,M
BIT 5,E RES 4,L SET 3,A
BIT 5,H RES 4,M SET 4,B
BIT 5,L RES 4,A SET 4,C
BIT 5,M RES 5,B SET 4,D
BIT 5,A RES 5,C SET 4,E
BIT 6,B RES 5,D SET 4,H
BIT 6,C RES 5,E SET 4,L
BIT 6,D RES 5,H SET 4,M
BIT 6,E RES 5,L SET 4,A
BIT 6,H RES 5,M SET 5,B
BIT 6,L RES 5,A SET 5,C
BIT 6,M RES 6,B SET 5,D
BIT 6,A RES 6,C SET 5,E
BIT 7,B RES 6,D SET 5,H
BIT 7,C RES 6,E SET 5,L
BIT 7,D RES 6,H SET 5,M
BIT 7,E RES 6,L SET 5,A
BIT 7,H RES 6,M SET 6,B
BIT 7,L RES 6,A SET 6,C
BIT 7,M RES 7,B SET 6,D
BIT 7,A RES 7,C SET 6,E
RES 0,B RES 7,D SET 6,H
RES 0,C RES 7,E SET 6,L
RES 0,D RES 7,H SET 6,M
RES 0,E RES 7,L SET 6,A
RES 0,H RES 7,M SET 7,B
RES 0,L RES 7,A SET 7,C
RES 0,M SET 0,B SET 7,D
RES 0,A SET 0,C SET 7,E
RES 1,B SET 0,D SET 7,H
RES 1,C SET 0,E SET 7,L
RES 1,D SET 0,H SET 7,M
RES 1,E SET 0,L SET 7,A
RES 1,H SET 0,M DADX B
RES 1,L SET 0,A DADX D
RES 1,M SET 1,B LXI X,06A4
RES 1,A SET 1,C SIXD 06A4
RES 2,B SET 1,D INX X
RES 2,C SET 1,E DADX X
RES 2,D SET 1,H LIXD 06A4
RES 2,E SET 1,L DCX X
RES 2,H SET 1,M INR [X+05]
RES 2,L SET 1,A DCR [X+05]
RES 2,M SET 2,B MVI [X+05],20
RES 2,A SET 2,C DADX SP
RES 3,B SET 2,D MOV B,[X+05]
RES 3,C SET 2,E MOV C,[X+05]
MOV D,[X+05] DSBC B DADY B
MOV E,[X+05] SBCD 06A4 DADY D
MOV H,[X+05] NEG LXI Y,06A4
MOV L,[X+05] RETN SIYD 06A4
MOV [X+05],B IM0 INX Y
MOV [X+05],C LDIA DADY Y
MOV [X+05],D INP C LIYD 06A4
MOV [X+05],E OUTP C DCX Y
MOV [X+05],H DADC B INR [Y+05]
MOV [X+05],L LBCD 06A4 DCR [Y+05]
MOV [X+05],A RETI MVI [Y+05],2
MOV A,[X+05] LDRA DADY SP
ADD [X+05] INP D MOV B,[Y+05]
ADC [X+05] OUTP D MOV C,[Y+05]
SUB [X+05] DSBC D MOV D,[Y+05]
SBB [X+05] SDED 06A4 MOV E,[Y+05]
ANA [X+05] IM1 MOV H,[Y+05]
XRA [X+05] LDAI MOV L,[Y+05]
ORA [X+05] INP E MOV [Y+05],B
CMP [X+05] OUTP E MOV [Y+05],C
POP X DADC D MOV [Y+05],D
XTIX LDED 06A4 MOV [Y+05],E
PUSH X IM2 MOV [Y+05],H
PCIX LDAR MOV [Y+05],L
SPIX INP H MOV [Y+05],A
RLCR [X+05] OUTP H MOV A,[Y+05]
RRCR [X+05] DSBC H ADD [Y+05]
RALR [X+05] shld 06A4 ADC [Y+05]
RARR [X+05] RRD SUB [Y+05]
SLAR [X+05] INP L SBB [Y+05]
SRAR [X+05] OUTP L ANA [Y+05]
SRLR [X+05] DADC H XRA [Y+05]
BIT 0,[X+05] lhld 06A4 ORA [Y+05]
BIT 1,[X+05] RLD CMP [Y+05]
BIT 2,[X+05] INP M POP Y
BIT 3,[X+05] OUTP M XTIY
BIT 4,[X+05] DSBC SP PUSH Y
BIT 5,[X+05] SSPD 06A4 PCIY
BIT 6,[X+05] INP A SPIY
BIT 7,[X+05] OUTP A RLCR [Y+05]
RES 0,[X+05] DADC SP RRCR [Y+05]
RES 1,[X+05] LSPD 06A4 RALR [Y+05]
RES 2,[X+05] LDI RARR [Y+05]
RES 3,[X+05] CCI SLAR [Y+05]
RES 4,[X+05] INI SRAR [Y+05]
RES 5,[X+05] OTI SRLR [Y+05]
RES 6,[X+05] LDD BIT 0,[Y+05]
RES 7,[X+05] CCD BIT 1,[Y+05]
SET 0,[X+05] IND BIT 2,[Y+05]
SET 1,[X+05] OTD BIT 3,[Y+05]
SET 2,[X+05] LDIR BIT 4,[Y+05]
SET 3,[X+05] CCIR BIT 5,[Y+05]
SET 4,[X+05] INIR BIT 6,[Y+05]
SET 5,[X+05] OTIR BIT 7,[Y+05]
SET 6,[X+05] LDDR RES 0,[Y+05]
SET 7,[X+05] CCDR RES 1,[Y+05]
INP B INDR RES 2,[Y+05]
OUTP B OTDR RES 3,[Y+05]
RES 4,[Y+05] SET 0,[Y+05] SET 4,[Y+05]
RES 5,[Y+05] SET 1,[Y+05] SET 5,[Y+05]
RES 6,[Y+05] SET 2,[Y+05] SET 6,[Y+05]
RES 7,[Y+05] SET 3,[Y+05] SET 7,[Y+05]
; These are the result of disassembling 64180OPS.TRY
; These opcodes are available ONLY on the 64180 CPU
; DDTZ will both assemble and disassemble these.
IN0 B,20 TST E MLT B
OUT0 20,B IN0 H,20 MLT D
TST B OUT0 20,H TSTI 20
IN0 C,20 TST H MLT H
OUT0 20,C IN0 L,20 TSIO 20
TST C OUT0 20,L SLP
IN0 D,20 TST L MLT SP
OUT0 20,D TST M OTIM
TST D IN0 A,20 OTDM
IN0 E,20 OUT0 20,A OIMR
OUT0 20,E TST A ODMR
; The following are UNDOCUMENTED z80 opcodes from XTDOPS.TRY.
; DDTZ will disassemble these, but will not assemble them.
; They use xh/xl (or yh/yl) as separate byte registers.
; Use these at your own risk.
INRX H ACXR H MOVY H,B
DCRX H ACXR L MOVY H,C
MVIX H,20 SUXR H MOVY H,D
INRX L SUXR L MOVY H,E
DCRX L SBXR H MOVY H,A
MVIX L,20 SBXR L MOVY L,B
MOVX B,H NDXR H MOVY L,C
MOVX B,L NDXR L MOVY L,D
MOVX C,H XRXR H MOVY L,E
MOVX C,L XRXR L MOVY L,A
MOVX D,H ORXR H MOVY A,H
MOVX D,L ORXR L MOVY A,L
MOVX E,H CPXR H ADYR H
MOVX E,L CPXR L ADYR L
MOVX H,B INRY H ACYR H
MOVX H,C DCRY H ACYR L
MOVX H,D MVIY H,20 SUYR H
MOVX H,E INRY L SUYR L
MOVX H,A DCRY L SBYR H
MOVX L,B MVIY L,20 SBYR L
MOVX L,C MOVY B,H NDYR H
MOVX L,D MOVY B,L NDYR L
MOVX L,E MOVY C,H XRYR H
MOVX L,A MOVY C,L XRYR L
MOVX A,H MOVY D,H ORYR H
MOVX A,L MOVY D,L ORYR L
ADXR H MOVY E,H CPYR H
ADXR L MOVY E,L CPYR L
Command Summary:
===============
DDTZM command DDTZ command
============= ============
@ (base)
A)ssemble first_address A
B)egin {i.e., initialize stack and return} B
C)ompare first_address,last_address,against_address C
D)ump first_address[,last_address[,base]] D
E)nter_in_memory first_address[,base] S)ubstitute
F)ill first_address,last_address,value F
G)o_to [address][,trap1[,trap2]] G
H)ex_arithmetic value1(,value2) H
L)oad_file (offset) R)ead
M)ove first_address,last_address,destination M
N)nput FCBs_command_line I)nput
Q)uit (not avail)
R)egister examine/change [register|flag] X)amine
S)earch first_address,last_address,word W)hereis
T)race_execution [count] T
Untrace_execution [count] (i.e. do count instr) U)ntrace
U)nassemble_code first_address[,last_address] L)ist code
W)rite [first_address,last_address] K)eep
X)amine {i.e. display memory parameters for application} Q)uery
Y)our_option BC:=parm1,DE:=parm2,call_address Y
Z)80_register_display Z
If you find this program useful, contributions will be gratefully
accepted and will encourage further development and release of
useful CPM programs. My practice is to include source.
C.B. Falconer
680 Hartford Turnpike,
Hamden, Conn. 06517 (203) 281-1438
DDTZ and its associated documentation and other files are
copyright (c) 1980-1988 by C.B. Falconer. They may be freely
copied and used for non-commercial purposes ONLY.
ôÙ

514
Doc/FDU.txt

@ -1,514 +0,0 @@
================================================================
Floppy Disk Utility (FDU) v5.3 for RetroBrew Computers
Disk IO / Zeta / Dual-IDE / N8 / RC2014 / SmallZ80 / Dyno
================================================================
Updated January 5, 2020
by Wayne Warthen (wwarthen@gmail.com)
Application to test the hardware functionality of the Floppy
Disk Controller (FDC) on the ECB DISK I/O, DISK I/O V3, ZETA
SBC, Dual IDE w/ Floppy, or N8 board.
The intent is to provide a testbed that allows direct testing
of all possible media types and modes of access. The
application supports read, write, and format by sector, track,
and disk as well as a random read/write test.
The application supports access modes of polling, interrupt,
INT/WAIT, and DRQ/WAIT. At present, it supports 3.5" media at
DD (720KB) and HD (1.44MB) capacities. It also now supports
5.25" media (720KB and 1.2MB) and 8" media (1.11MB) as well.
Additional media will be added when I have time and access to
required hardware. Not all modes are supported on all
platforms and some modes are experimental in all cases.
In many ways this application is merely reinventing the wheel
and performs functionality similar to existing applications,
but I have not seen any other applications for RetroBrew
Computers hardware that provide this range of functionality.
While the application is now almost entirely new code, I would
like to acknowledge that much was derived from the previous
work of Andrew Lynch and Dan Werner. I also want to credit
Sergio Gimenez with testing the 5.25" drive support and Jim
Harre with testing the 8" drive support. Support for Zeta 2
comes from Segey Kiselev. Thanks!
General Usage
-------------
In general, usage is self explanatory. At invocation, you
must select the floppy disk controller (FDC) that you are
using. Subsequently, the main menu allows you to set the
unit, media, and mode to test. These settings MUST match your
situation. Read, write, format, and verify functions are
provided. A sub-menu will allow you to choose sector, track,
disk, or random tests.
The verify function requires a little explanation. It will
take the contents of the current in-memory disk buffer, save
it, and compare it to the selected sectors. So, you must
ensure that the sectors to be verified already have been
written with the same pattern as the buffer contains. I
typically init the buffer to a pattern, write the pattern to
the entire disk, then verify the entire disk.
Another submenu is provided for FDC commands. This sub-menu
allows you to send low-level commands directly to FDC. You
*must* know what you are doing to use this sub-menu. For
example, in order to read a sector using this sub-menu, you
will need to perform specify, seek, sense int, and read
commands specifying correct values (nothing is value checked
in this menu).
Required Hardware/BIOS
----------------------
Of course, the starting point is to have a supported hardware
configuration. The following Z80 / Z180 based CPU boards are
supported:
- SBC V1/2
- Zeta
- Zeta 2
- N8
- Mark IV
- RC2014 w/ SMC
- RC2014 w/ WDC
- SmallZ80
- Dyno
You must be using either a RomWBW or UBA based OS version.
You must have one of the following floppy disk controllers:
- Disk IO ECB Board FDC
- Disk IO 3 ECB Board FDC
- Dual-IDE ECB Board FDC
- Zeta SBC onboard FDC
- Zeta 2 SBC onboard FDC
- N8 SBC onboard FDC
- RC2014 Scott Baker SMC-based Floppy Module
- RC2014 Scott Baker WDC-based Floppy Module
Finally, you will need a floppy drive connected via an
appropriate cable:
Disk IO - no twist in cable, drive unit 0/1 must be selected by jumper on drive
DISK IO 3, Zeta, Zeta 2, RC2014, Dyno - cable with twist, unit 0 after twist, unit 1 before twist
DIDE, N8, Mark IV, SmallZ80 - cable with twist, unit 0 before twist, unit 1 after twist
Note that FDU does not utilize your systems ROM or OS to
access the floppy system. FDU interacts directly with
hardware. Upon exit, you may need to reset your OS to get the
floppy system back into a state that is expected.
The Disk I/O should be jumpered as follows:
J1: depends on use of interrupt modes (see interrupt modes below)
J2: pins 1-2, & 3-4 jumpered
J3: hardware dependent timing for DMA mode (see DMA modes below)
J4: pins 2-3 jumpered
J5: off
J6: pins 2-3 jumpered
J7: pins 2-3 jumpered
J8: off
J9: off
J10: off
J11: off
J12: off
Note that J1 can be left on even when not using interrupt
modes. As long as the BIOS is OK with it, that is fine. Note
also that J3 is only relevant for DMA modes, but also can be
left in place when using other modes.
The Disk I/O 3 board should be jumpered at the default settings:
JP2: 3-4
JP3: 1-2 for int mode support, otherwise no jumper
JP4: 1-2, 3-4
JP5: 1-2
JP6: 1-2
JP7: 1-2, 3-4
Zeta & Zeta 2 do not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
The Dual-IDE board should be jumpered as follows:
K3 (DT/R or /RD): /RD
P5 (bd ID): 1-2, 3-4 (for $20-$3F port range)
There are no specific N8 jumper settings, but the default
I/O range starting at $80 is assumed in the published code.
The RC2014 Scott Baker SMC-based floppy module should be jumpered
for I/O base address 0x50 (SV1: 11-12), JP1 (TS) shorted,
JP2 (/FAULT) shorted, JP3 (MINI): 2-3, JP4 (/DC/RDY): 2-3.
The RC2014 Scott Baker WDC-based floppy module should be jumpered
for I/O base address 0x50 (SV1: 11-12), JP1 (/DACK): 1-2,
JP2 (TC): 2-3.
SmallZ80 does not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
Dyno does not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
Modes of Operation
------------------
You can select the following test modes. Please refer to the
chart that follows to determine which modes should work with
combinations of Z80 CPU speed and media format.
WARNING: In general, only the polling mode is considered fully
reliable. The other modes are basically experimental and
should only be used if you know exactly what you are doing.
Polling: Traditional polled input/output. Works well and very
reliable with robust timeouts and good error recovery. Also,
the slowest performance which precludes it from being used
with 1.44MB floppy on a 4MHz Z80. This is definitely the mode
you want to get working before any others. It does not require
J1 (interrupt enable) on DISK I/O and does not care about the
setting of J3.
Interrupt: Relies on FDC interrupts to determine when a byte
is ready to be read/written. It does *not* implement a
timeout during disk operations. For example, if there is no
disk in the drive, this mode will just hang until a disk is
inserted. This mode *requires* that the host has interrupts
active using interrupt mode 1 (IM1) and interrupts attached to
the FDC controller. The BIOS must be configured to handle
these interrupts safely.
Fast Interrupt: Same as above, but sacrifices additional
reliability for faster operation. This mode will allow a
1.44MB floppy to work with a 4MHz Z80 CPU. However, if any
errors occur (even a transient read error which is not
unusual), this mode will hang. The same FDC interrupt
requirements as above are required.
INT/WAIT: Same as Fast Interrupt, but uses CPU wait instead of
actual interrupt. This mode is exclusive to the original Disk
IO board. It is subject to all the same issues as Fast
Interrupt, but does not need J1 shorted. J3 is irrelevant.
DRQ/WAIT: Uses pseudo DMA to handle input/output. Does not
require that interrupts (J1) be enabled on the DISK I/O.
However, it is subject to all of the same reliability issues
as "Fast Interrupt". This mode is exclusive to the original
Disk IO board. At present, the mode is *not* implemented!
The chart below attempts to describe the combinations that
work for me. By far, the most reliable mode is Polling, but
it requires 8MHz CPU for HD disks.
DRQ/WAIT --------------------------------+
INT/WAIT -----------------------------+ |
Fast Interrupt --------------------+ | |
Interrupt ----------------------+ | | |
Polling ---------------------+ | | | |
| | | | |
CPU Speed --------------+ | | | | |
| | | | | |
| | | | | |
3.5" DD (720K) ------ 4MHz Y Y Y Y X
8MHz+ Y Y Y Y X
3.5" HD (1.44M) ----- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
5.25" DD (360K) ----- 4MHz Y Y Y Y X
8MHz+ Y Y Y Y X
5.25" HD (1.2M) ----- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
8" DD (1.11M) ------- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
Y = Yes, works
N = No, does not work
X = Experimental, probably won't work
Tracing
-------
Command/result activity to/from the FDC will be written out if
the trace setting is changed from '00' to '01' in setup.
Additionally, if a command failure is detected on any command,
that specific comand and results are written regardless of the
trace setting.
The format of the line written is:
<OPERATION>: <COMMAND BYTES> --> <RESULT BYTES> [<RESULT>]
For example, this is the output of a normal read operation:
READ: 46 01 00 00 01 02 09 1B FF --> 01 00 00 00 00 02 02 [OK]
Please refer to the i8272 data sheet for information on the
command and result bytes.
Note that the sense interrupt command can return a non-OK
result. This is completely normal in some cases. It is
necessary to "poll" the drive for seek status using sense
interrupt. If there is nothing to report, then the result
will be INVALID COMMAND. Additionally, during a recalibrate
operation, it may be necessary to issue the command twice
because the command will only step the drive 77 times looking
for track 0, but the head may be up to 80 tracks away. In
this case, the first recalibrate fails, but the second should
succeed. Here is what this would look like if trace is turned
on:
RECALIBRATE: 07 01 --> <EMPTY> [OK]
SENSE INTERRUPT: 08 --> 80 [INVALID COMMAND]
...
...
...
SENSE INTERRUPT: 08 --> 80 [INVALID COMMAND]
SENSE INTERRUPT: 08 --> 71 00 [ABNORMAL TERMINATION]
RECALIBRATE: 07 01 --> <EMPTY> [OK]
SENSE INTERRUPT: 08 --> 21 00 [OK]
Another example is when the FDC has just been reset. In this
case, you will see up to 4 disk change errors. Again these
are not a real problem and to be expected.
When tracing is turned off, the application tries to be
intelligent about error reporting. The specific errors from
sense interrupt documented above will be suppressed because
they are not a real problem. All other errors will be
displayed.
Error Handling
--------------
There is no automated error retry logic. This is very
intentional since the point is to expose the controller and
drive activity. Any error detected will result in a prompt to
abort, retry, or continue. Note that some number of errors is
considered normal for this technology. An occasional error
would not necessarily be considered a problem.
CPU Speed
---------
Starting with v5.0, the application adjusts it's timing loops
to the actual system CPU speed by querying the BIOS for the
current CPU speed.
Interleave
----------
The format command now allows the specification of a sector
interleave. It is almost always the case that the optimal
interleave will be 2 (meaning 2:1).
360K Media
----------
The 360K media definition should work well for true 360K
drives. However, it will generally not work with 1.2M
drives. This is because these drives spin at 360RPM instead
of the 300RPM speed of true 360K drives. Additionally, 1.2M
drives are 80 tracks and 360K drives are 40 tracks and, so
far, there is no mechanism in FD to "double step" as a way to
use 40 track media in 80 track drives.
With this said, it is possible to configure some 1.2M 5.25"
drives to automatically spin down to 300RPM based on a density
select signal (DENSEL). This signal is asserted by FD for
360K media, so IF you have configured your drive to react to
this signal correctly, you will be able to use the 360K media
defintion. Most 1.2M 5.25" drives are NOT configured this way
by default. TEAC drives are generally easy to modify and have
been tested by the author and do work in this manner. Note
that this does not address the issue of double stepping above;
you will just be using the first 40 of 80 tracks.
Support
-------
I am happy to answer questions as fast and well as I am able.
Best contact is wwarthen@gmail.com or post something on the
RetroBrew Computers Forum
https://www.retrobrewcomputers.org/forum/.
Changes
-------
WW 8/12/2011
Removed call to pulse TC in the FDC initialization after
determining that it periodically caused the FDC to write bad
sectors. I am mystified by this, but definitely found it to
be true. Will revisit at some point -- probably a timing
issue between puslsing TC and whatever happens next.
Non-DMA mode was being set incorrectly for FAST-DMA mode. It
was set for non-DMA even though we were doing DMA. It is
interesting that it worked fine anyway. Fixed it anyway.
DIO_SETMEDIA was not clearing DCD_DSKRDY as it should. Fixed.
WW 8/26/2011: v1.1
Added support for Zeta. Note that INT/WAIT and DRQ/WAIT are
not available on Zeta. Note that Zeta provides the ability to
perform a reset of the FDC independent of a full CPU reset.
This is VERY useful and the FDC is reset anytime a drive reset
is required.
Added INT/WAIT support.
WW 8/28/2011: V1.2
All changes in this version are Zeta specific. Fixed FDC
reset logic and motor status display for Zeta (code from
Sergey).
Modified Zeta disk change display to include it in the command
output line. This makes more sense because a command must be
issued to select the desired drive first. You can use the
SENSE INT command id you want to check the disk change value
at any time. It will also be displayed with any other command
output display.
WW 9/1/2011: V1.3
Added CPUFREQ configuration setting to tune delays based on
cpu speed. The build app is set for 8MHz which also seems to
work well for 4MHz CPU's. Faster CPU speeds will probably
require tuning this setting.
WW 9/5/2011: V1.4
Changed the polling execution routines to utilize CPUFREQ
variable to optimize timeout counter. Most importantly, this
should allow the use of faster CPUs (like 20MHz).
WW 9/19/2011: V1.5
Zeta changes only. Added a call to FDC RESET after any
command failure. This solves an issue where the drive remains
selected if a command error occurs. Also added FDC RESET to
FDC CONTROL menu.
WW 10/7/2011: V2.0
Added support for DIDE. Only supports polling IO and it does
not appear any other modes are possible given the hardware
constraints.
WW 10/13/2011: V2.1
Modified to support N8. N8 is essentially identical to Dual
IDE. The only real change is the IO addresses. In theory, I
should be able to support true DMA on N8 and will work on that.
WW 10/20/2011: v2.2
I had some problems with the results being read were sometimes
missing a byte. Fixed this by taking a more strict approach
to watching the MSR for the exact bits that are expected.
WW 10/22/2011: V2.3
After spending a few days trying to track down an intermittent
data corruption issue with my Dual IDE board, I added a verify
function. This helped me isolate the problem very nicely
(turned out to be interference from the bus monitor).
WW 11/25/2011: V2.4
Preliminary support for DISKIO V3. Basically just assumed
that it operates just like the Zeta. Needs to be verified
with real hardware as soon as I can.
WW 1/9/2012: V2.5
Modified program termination to use CP/M reset call so that a
warm start is done and all drives are logged out. This is
important because media may have been formatted during the
program execution.
WW 2/6/2012: v2.6
Added support for 5.25" drives as tested by Sergio.
WW 4/5/2012: v2.7
Added support for 8" drives as tested by Jim Harre.
WW 4/6/2012: v2.7a
Fixed issue with media selection menu to remove duplicate
entries.
WW 4/8/2012: v2.7b
Corrected the handling of the density select signal.
WW 5/22/2012: v2.8
Added new media definitions (5.25", 320K).
WW 6/1/2012: v2.9
Added interleave capability on format.
WW 6/5/2012: v3.0
Documentation cleanup.
WW 7/1/2012: v3.1
Modified head load time (HLT) for 8" media based on YD-180
spec. Now set to 50ms.
WW 6/17/2013: v3.2
Cleaned up SRT, HLT, and HUT values.
SK 2/10/2015: v3.3
Added Zeta SBC v2 support (Sergey Kiselev)
WW 3/25/2015: v4.0
Renamed from FDTST --> FD
WW 9/2/2017: v5.0
Renamed from FD to FDU.
Added runtime selection of FDC hardware.
Added runtime timing adjustment.
WW 12/16/2017: v5.1
Improved polling version of read/write to fix occasional overrun errors.
WW 1/8/2018: v5.2
Added support for RC2014 hardware:
- Scott Baker SMC 9266 FDC module
- Scott Baker WDC 37C65 FDC module
WW 9/5/2018: v5.3
- Removed use of pulsing TC to end R/W operations after one sector and
instead set EOT = R (sector number) so that after desired sector is
read, R/W stops with end of cylinder error which is a documented
method for controling number of sectors R/W. This specific termination
condition is no longer considered an error, but a successful end of
operation.
- Added support for SmallZ80
WW 5/1/2020: v5.4
- Added support for Dyno (based on work by Steve Garcia)

BIN
Doc/Hard Disk Anatomy.pdf

Binary file not shown.

BIN
Doc/Microsoft Basic-80 Reference Manual v5.0.pdf

Binary file not shown.

89
Doc/ReadMe.txt

@ -10,6 +10,26 @@ This directory ("Doc") is part of the RomWBW System Software
distribution archive. It contains documentation for components of distribution archive. It contains documentation for components of
the system. the system.
ChangeLog.txt
-------------
Log of changes in RomWBW by version.
RomWBW User Guide ("RomWBW User Guide.pdf")
RomWBW System Guide ("RomWBW System Guide.pdf")
RomWBW Applications ("RomWBW Applications.pdf")
RomWBW ROM Applications ("RomWBW ROM Applications.pdf")
RomWBW Disk Catalog ("RomWBW Disk Catalog.pdf")
RomWBW Errata ("RomWBW Errata.pdf")
-------------------------------------------------------
Documentation set for RomWBW. The primary document is the
User Guide. The System Guide explains internal system operation
and has a reference for the HBIOS API. Use of included tools
and utilities are detailed in the Applications and
ROM Applications documents.
CPM Manual ("CPM Manual.pdf") CPM Manual ("CPM Manual.pdf")
----------------------------- -----------------------------
@ -43,12 +63,6 @@ The operational manual for John Coffman's hard disk partitioning
program. This program is included in RomWBW as FDISK80. program. This program is included in RomWBW as FDISK80.
Floppy Disk Utility Documentation ("FDU.tst")
---------------------------------------------
Operational documentation for the RomWBW FDU application.
Hard Disk Anatomy ("Hard Disk Anatomy.pdf") Hard Disk Anatomy ("Hard Disk Anatomy.pdf")
------------------------------------------- -------------------------------------------
@ -61,22 +75,6 @@ NZCOM User's Manual ("NZCOM Users Manual.pdf")
NZCOM operating system operation manual. NZCOM operating system operation manual.
RomWBW Architecture ("RomWBW Architecture.pdf")
-----------------------------------------------
Document describing the architecture of the RomWBW HBIOS. It
includes reference information for the HBIOS calls.
Z180 ASCI Baud Rate Options ("Z180 ASCI Baud Rate Options.pdf")
---------------------------------------------------------------
The Z180 processor's ASCI serial ports have a limited set of
baud rate divisors. These divisors are relative to the CPU
clock rate. This document provides a list of the possible
baud rates for typical CPU clock rates.
ZCPR Manual ("ZCPR Manual.pdf") ZCPR Manual ("ZCPR Manual.pdf")
------------------------------- -------------------------------
@ -85,11 +83,54 @@ manual for ZCPR 1.x as included in RomWBW. The installation
instructions can be ignored since that work has already been instructions can be ignored since that work has already been
completed as part of the RomWBW distribution. completed as part of the RomWBW distribution.
ZCPR D&J Manual ("ZCPR-DJ.doc")
-------------------------------
ZCPR D&J User Manual. This manual supplements the ZCPR Manual.
ZSDOS Manual ("ZSDOS Manual.pdf") ZSDOS Manual ("ZSDOS Manual.pdf")
--------------------------------- ---------------------------------
ZSDOS is the DOS portion of Z-System. This is the manual fo ZSDOS
ZSDOS is the DOS portion of Z-System. This is the manual for ZSDOS
1.x as included in RomWBW. The installation instructions can be 1.x as included in RomWBW. The installation instructions can be
ignored since that work has already been completed as part of the ignored since that work has already been completed as part of the
RomWBW distribution.
RomWBW distribution.
Microsoft Basic-80 Reference Manual v5.0 (Microsoft Basic-80 Reference Manual v5.0.pdf)
---------------------------------------------------------------------------------------
Official manual for Microsoft BASIC as included in RomWBW.
QP/M 2.7 Installation Guide and Supplements ("qpm27.pdf")
QP/M 2.7 Interface Guide ("qdos27.pdf")
QP/M 2.7 Features and Facilities ("qcp27.pdf")
--------------------------------------------
Official documentation set for QP/M 2.7 from original QP/M distribution.
SIO+CTC Baud Rate Options (SIO+CTC Baud Rate Options.pdf)
---------------------------------------------------------
Documents possible baud rates available based on different baud
clock rates for Zilog SIO using CTC for baud rate clock generation.
Z180 ASCI Baud Rate Options ("Z180 ASCI Baud Rate Options.pdf")
---------------------------------------------------------------
The Z180 processor's ASCI serial ports have a limited set of
baud rate divisors. These divisors are relative to the CPU
clock rate. This document provides a list of the possible
baud rates for typical CPU clock rates.
UCSD p-System Users Manual ("UCSD p-System Users Manual.pdf")
-------------------------------------------------------------
Official user manual for p-System operating system included with
RomWBW.
--WBW 5:18 PM 3/16/2023

BIN
Doc/RomWBW Applications.pdf

Binary file not shown.

BIN
Doc/RomWBW Architecture.pdf

Binary file not shown.

BIN
Doc/RomWBW Disk Catalog.pdf

Binary file not shown.

BIN
Doc/RomWBW Errata.pdf

Binary file not shown.

BIN
Doc/RomWBW Getting Started.pdf

Binary file not shown.

BIN
Doc/RomWBW ROM Applications.pdf

Binary file not shown.

BIN
Doc/RomWBW System Guide.pdf

Binary file not shown.

BIN
Doc/RomWBW User Guide.pdf

Binary file not shown.

BIN
Doc/SIO+CTC Baud Rate Options.pdf

Binary file not shown.

25
Doc/Testing Notes.txt

@ -23,7 +23,7 @@ Zeta 2 (X)
- Test FD driver - Test FD driver
- Test FDU app - Test FDU app
RC2014 (X)
RCBus (X)
------ ------
- Test SIO driver (Serial Module) - Test SIO driver (Serial Module)
- Test ACIA driver (Dual Serial Module) - Test ACIA driver (Dual Serial Module)
@ -40,7 +40,7 @@ N8-2312 (X)
- Test FDU app - Test FDU app
- Test TMS driver (video & kbd) - Test TMS driver (video & kbd)
N8-2511 ( )
N8-2511 (X)
------- -------
- Test ASCI driver - Test ASCI driver
- Test SD driver (Juha mode) - Test SD driver (Juha mode)
@ -139,27 +139,6 @@ GENERAL (X)
- ASSIGN app - ASSIGN app
- MODE app - MODE app
- SYSCOPY app - SYSCOPY app
- OSLDR app
- FDU app - FDU app
- FDISK80 app - FDISK80 app
- TUNE app - TUNE app
RESULTS
-------
- Missing HBIOS startup banner (X)
- PANIC while printing Serial device inventory (X)
- Unexpected interrupt signals not handled well (X)
- Fix IT_??? usage (X)
- Fix HB_DI/HB_EI in PEEK/POKE/BNKCPY (X)
- Fix SIMH timer interrupt setup (X)
- Move DI/EI in PEEK/POKE/BNKCPY to API layer? (X)
- RETI vs. JP in page zero when INTMODE = 0 (X)
- Check interrupt stack space (X)
- If an early INT fires, we return with INTs enabled (not good) (X)
- PPPCON init should display ANSI 80x25 or similar (X)
- Add INT MODE X message to early boot messages (X)
- OSLDR fails when LDDS is loaded (X)
- Add "!!!" to force assembly error as needed ( )
- TIMER app should check for HBIOS active (X)
- Halt system after bad interrupt??? ( )
- Adapt and bundle PLAYER.COM (X)

BIN
Doc/UCSD p-System Users Manual.pdf

Binary file not shown.

BIN
Doc/Z180 ASCI Baud Rate Options.pdf

Binary file not shown.

765
Doc/ZCPR-DJ.doc

@ -0,0 +1,765 @@
A Personal Note
===============
Somehow, I've managed to get by for the last 14 years using just ZCPR.
But like some of you, I have fiddled with the standard ZCPR and
modified it to suit my tastes. As I added new commands or enriched old
ones, I've always remained compatible with existing programs, all the
BDOS replacements, and, most important of all, stayed within the 800H
space allocation of the original Digital Research CCP. Here are the
fruits of my labors, I hope you enjoy this CCP replacement as much as I
do.
Don Kirkpatrick
17595 S.W. Pheasant Lane
Beaverton, Oregon 97006
<Donald.C.Kirkpatrick@tek.com>
Introduction
============
This console replacement is designed to run under CP/M 2.2 or any of
the 2.2 BDOS replacements. It requires a Z80 or better. If you are
running DRI's CCP or older versions of ZCPR1, this program is a
significant improvement. If you are running ZCPR3, CP/M 3.0, CP/M
Plus, or MP/M, this will probably be a disappointment.
If you are familiar with ZCPR3, you will recognize many of the
enhancements here: comments on a command line, search path for the .com
file, drive/user change with simple du:, CLEVEL3 command processing,
proper SUBMIT file facility, and so on. Nothing has been removed from
DRI's CCP, only new features added. AND IT ALL STILL FITS IN THE
ORIGINAL 800H, THE SAME SPACE AS THE DIGITAL RESEARCH FIVE COMMAND
CCP.
Many of the standard commands have been enhanced. For example, TYPE
and LIST now have options to turn on or off page breaks. Moreover, the
console check for abort has been improved.
Two commands have been added for use in submit files - SAK and BELL.
These commands allow you to pause or ring the bell during submit file
execution.
Before you install this version of ZCPR onto your boot disks, try it by
running it as a .com file. Just edit the few customizing options and
assemble the source. After you decide it really is better, load it
onto your boot track and make it your standard. Complete instructions
are located at the end of this document.
The complete built-in command list is:
DIR - directory command enhanced to list optionally all user areas
REN - standard rename command
USER- move to new user number area on same drive
SAVE- save specified number of TPA pages or records in a file
TYPE- display a file on the console with optional page break pauses
LIST- print command plus optional form feed insertion
PAGE- send form feed to list device
ERA - standard file erase command
ERAQ- file erase with confirmation query at each file
DFU - set default user number for .com search path
BELL- send a bell character to the console
SAK - pause until a key is struck on the console (Strike Any Key)
SCL - toggle multiple commands per line (Single Command on a Line)
GET - load a file into the TPA at any specified location
JUMP- process command tail and execute program at specified address
GO - process command tail and execute program loaded at 100H
PEEK- display hexadecimal byte string starting with specified address
POKE- load hexadecimal byte string starting with specified address
BOOT- execute BIOS cold boot routine
Filename Processing
===================
The standard ZCPR3 du: drive/user file specification has been
implemented. Any filename can be in the du:fn.ft form. For example:
A>era c4:junk*.*
erases files on the C drive, user area 4 without leaving drive A user
0. When a user number is found in a filename, that user number is
placed in S1 of the default FCB. Bit 7 of S1 is set to inform the
program using the FCB a user number was found.
The * in an ambiguous file name has been improved. Now a trailing *
causes the remainder of the ambiguous name to be filled with '?', not
just the fn field. For example:
A>era c4:junk*
is the same as the example above. Previously, junk* was defined as
'junk????. '. If you need the ft field blank, type 'junk*.'. The
question mark still works as a single character wild card.
Command Line Processing
=======================
The current user number is included as part of the command prompt for
all non-zero user numbers. The prompt is of the form du>, for example
A2> or B10>. If the SUPRES equate is true, the user number is
suppressed for user 0 only.
Multiple commands are typed on a single line separated by a command
separator character. Occasionally, you need to type the separator
character in a command tail. The SCL command toggles the multiple
command enable. The CMDCHR equate determines the command separator
character. A ';' has been chosen as the separator character in this
distribution version.
Comments are allowed on a command line. When the comment separator
character is encountered as the first character of a command, the
remainder of the line is ignored. The COMCHR equate determines the
comment separator character. A ';' has been chosen as the separator
character in this distribution version. Here is an example containing
comments and multiple commands on a single line:
A>get 100 junk;peek 100;;this is a comment.
A>;this is also a comment.
There exists a built-in search path for transient commands. First, the
current drive/user is searched. Next, the current drive/default user
is searched. Last, drive A/default user is searched. The DEFUSR
equate determines the default user number, currently set to user 0 in
this distribution version. The default user is temporarily changed
with the DFU command. If a drive is specified in the transient
command, the current and default user areas on the specified drive are
searched. If a user number is specified, that user area on the current
and default drive are searched. If both the drive and user number are
specified, no search is performed. The same drive/user area is never
searched twice.
Transient commands are always "called." If a program terminates via a
return rather than a warm boot, subsequent multiple commands on the
command line are executed. Any program exiting by a warm boot reloads
ZCPR and the subsequent commands lost.
A default command can be placed in the command buffer and control
passed to ZCPR for processing. The only thing required, besides
placing the command in the buffer and jumping to CPRLOC, is to
initialize the command character counter at the start of the buffer.
The procedure is compatible with the original DRI CCP default command
processing. If ZCPR is entered at CPRLOC+3 jump, default command
processing is suppressed. Either way, register C must contain a valid
drive/user, just like the original CCP.
Submit File Processing
======================
A basic design choice had to be made in the design of ZCPR concerning
the execution of submit files. The original CCP had a problem. It
ALWAYS looked for the $$$.SUB file on drive A and the submit program
would place it on the current default drive. When the you were logged
onto drive B and you issued a submit command, the $$$.SUB was placed on
drive B and not executed.
After much debate it was decided to have ZCPR perform the same type of
function as CCP (look for the $$$.SUB file on drive A), but the problem
with SUBMIT.COM still exists. Hence, RGF designed SuperSUB and RLC
took his SuperSUB and designed SUB from it; both programs are set up to
allow the selection at assembly time of creating the $$$.SUB on the
default drive or on drive A. If you don't have one of these newer
submit programs, a procedure for patching the standard SUBMIT.COM has
been included at the end.
The fixed drive choice permits a submit file to contain a series of
commands exactly as they would be entered from a CP/M console. This
permits things like:
A>dir
A>b:
B>dir
to be executed, even though the currently default drive is changed
during execution. If the $$$.SUB file were present on the default
drive, the above series of commands would not work. ZCPR would be
looking for $$$.SUB on the default drive, and switching default drives
without moving the $$$.SUB file would cause processing to abort. Note
that the same problem occurs if the user number of the $$$.SUB file is
not predefined. ZCPR assumes that the $$$.SUB file is located on user 0
of drive A.
The trick of using the $ flag returned by the BDOS disk reset is used
to speed the search for a $*.* file on drive A. This trick will not
work if the $$$.SUB file were located on another drive.
The '>' prompt character is replaced by a special character while a
submit file is in execution. The SPRMPT equate defines this special
character, currently set to '$' in this distribution version.
Command Syntax
==============
Multiple commands can be placed on one line. If the comment character
is encountered where a command should start, the rest of the line is
ignored. Any command can be renamed by editing the command table.
Command names can be up to eight characters long and are terminated by
bit 7 high. If there is a conflict between an internal ZCPR command
and a transient program of the same name, the internal command is
executed. Type the command with the du: included if the external
transient command is the one desired. Here is a complete alphabetized
list of all the resident commands with their syntax:
=============================================================================
Command: BELL
Function: To ring terminal bell.
Forms: BELL
Options: None.
Uses: This command is designed to be placed in a submit file to
ring the bell to indicate significant checkpoints.
=============================================================================
Command: BOOT
Function: To execute BIOS cold boot routine.
Forms: BOOT
Options: REBOOT equate controls the inclusion/exclusion of this command.
Uses: Reboots the system without pushing the reset button. The
cold boot entry point in the BIOS must be supported for this
command to work.
=============================================================================
Command: DFU
Function: To set the Default User Number for transient commands.
Forms: DFU <usrnum>
Options: DEFUSR equate defines the default user choice until this
command is entered.
NUMBASE equate defines the character that specifies a
hexadecimal number. The distribution version is set to 'H'.
Uses: The default user area is searched after a transient command
cannot be found in the current user area. If the transient
command still has not been found, the default user on the
default drive is searched last. The new default user number
is in decimal, but hexadecimal numbers are entered by
appending an 'H'. The next warm boot will restore the
original default user number.
=============================================================================
Command: DIR
Function: To display a directory listing of the files on a drive.
Forms: DIR <afn> Display the DIR files
DIR <afn> S Display the SYS files
DIR <afn> B Display both DIR and SYS files
DIR <afn> A Display both DIR and SYS files for all user areas
Options: TWOCOL equate controls the number of columns in the display.
Forty-column terminals are limited to two-column displays.
WIDE equate controls the spacing between the columns and
change the horizontal width of a directory display.
FENCE equate specifies the character separator between the
directory columns.
USRDLM equate specifies the character between the user number
and the filename.
USRFLG, SYSFLG, and SOFLG equates specify the command line
tail character that control the display of system and
non-system files.
Uses: Displays a directory listing of files in specific drive/user
area.
=============================================================================
Command: ERA
Function: To erase files.
Forms: ERA <afn>
Options: None.
Uses: Deletes files. Names of erased files are displayed.
=============================================================================
Command: ERAQ
Function: To erase files with individual query.
Forms: ERAQ <afn>
<afn>? y File erased
<afn>? <CR> File not erased
Options: None.
Uses: Deletes a subset of a set of ambiguously specified files.
Any answer other than 'Y' (either case) will cause the file
to be skipped and not erased.
=============================================================================
Command: GET
Function: To load the specified file from disk to the specified address.
Forms: GET <hexadr> <ufn>
Options: None.
Uses: Loads a file into the TPA for patching purposes. This command
searches for the specified file along the same search path as
the transient command loader.
=============================================================================
Command: GO
Function: To call the program in the TPA without loading from disk.
Forms: GO <command tail>
Options: None.
Uses: Most useful to rerun a program already loaded into the TPA.
Saves time and wear on disk drives. The command tail is
entered exactly as it would appear if GO were replaced by the
program name. Same as JUMP 100H, but more convenient,
especially when used with parameters for programs like STAT.
=============================================================================
Command: JUMP
Function: To call the program at a specified address.
Forms: JUMP <hexadr> <command tail>
Options: None.
Uses: Executes code not located at 100H. For example, JUMP 0
warm boots. The code must already reside at the specified
address.
=============================================================================
Command: LIST
Function: To print specified file on list device.
-
Forms: LIST <ufn> Print file
LIST <ufn> P Print file without default paging
Options: NLINEP equate determines the number of lines per page.
FFKILL equate controls the suppression of form feeds before
printable text.
PGDFLG equate determines the command line tail character that
toggles the default form feed insertion every NLINEP lines.
NOSTAT equate controls the use of the BIOS list status call.
Uses: Prints files with/without pagination on LST: device. A
listing is aborted by a console ^C. Any submit file in
process is terminated and control is returned gracefully to
the console prompt.
=============================================================================
Command: PAGE
Function: To eject a page on list device via a form feed.
Forms: PAGE
Options: NOSTAT equate controls the use of the BIOS list status call.
Uses: Sends a form feed to the LST: device. The page eject can
be aborted by a console ^C if the system hangs because the
printer is not ready. If aborted, any submit file in process
is terminated and control is returned gracefully to the
console prompt.
=============================================================================
Command: PEEK
Function: To display hex values beginning at a specified address.
Forms: PEEK <hexadr> [<hexcnt>]
Options: None.
Uses: Displays hexadecimal values anywhere in the entire address
space. The maximum value for <hexcnt> is 0FFH, but the
default <hexcnt> is 256.
=============================================================================
Command: POKE
Function: To poke a string of hex values into a set of consecutive
addresses.
Forms: POKE <hexadr> <hexval> [...<hexval>]
Options: None.
Uses: Modifies values anywhere in the entire address space. Each
<hexval> represents one byte and is separated from the next
by a space. The number of <hexval> are limited only by the
size of the command line buffer. The address is incremented
for each <hexval>. Excellent for hand patching code.
=============================================================================
Command: REN
Function: To change the name of an existing file.
Forms: REN <newufn>=<oldufn>
REN <newufn>=<oldufn> Existing <newufn>
Delete? y File deleted
Options: None.
Uses: Changes the names of files. Any du: on <oldufn> is ignored;
the optional du: is on <newufn>. If there already exists a
<newufn>, the console is queried for conformation. Any
response except 'Y' (either case) aborts the command, kills
any submit file in process, and returns gracefully to the
command prompt.
=============================================================================
Command: SAK
Function: To pause until a key is struck.
Forms: SAK
? <any key>
Options: None.
Uses: Pauses a submit file until a keystroke is entered. Any
character other than a ^C will resume execution. A ^C kills
the submit file, any commands remaining on the command the
line are ignored, and control returns gracefully to the
prompt.
=============================================================================
Command: SAVE
Function: To save the contents of TPA onto disk as a file.
Forms: SAVE <Number of Pages> <ufn>
SAVE <Number of Records> <ufn> R
Options: RECFLG equate determines the command tail character that
specifies records rather than pages.
NUMBASE equate defines the character that specifies a
hexadecimal number. The distribution version is set to 'H'.
Uses: Saves the TPA to a file. Records are 128 bytes long, pages
are 256 bytes long. Number of pages or records is in
decimal, but a hexadecimal number is entered by appending an
'H'. Saved area begins at 100H.
=============================================================================
Command: SCL
Function: To force ZCPR to parse only a single command per line.
Forms: SCL
Options: MULTPL equate determines the inclusion/exclusion of this
command and whether or not multiple commands are allowed.
CMDCHR equate determines the character separating multiple
commands.
Uses: Some transient commands require the command separator in the
command tail. This command turns off multiple command
parsing so the entire command tail is sent to the transient
program. Multiple command format is reset at the next warm
boot. SCL toggles.
=============================================================================
Command: TYPE
Function: To display specified file on console.
Forms: TYPE <ufn> Display file
TYPE <ufn> P Display file without default paging
Options: NLINES equate determines the number of lines per screen.
FFKILL equate controls the suppression of form feeds before
printable text.
PGDFLG equate determines the command line tail character that
toggles the default form feed insertion every NLINEP lines.
Uses: Displays files with/without pagination on CON: device. A
display is aborted by a console ^C. If aborted, any submit
file in process terminates and control returns gracefully to
the console prompt. When page breaks are enabled, any
console character except ^C will display the next page of
text.
=============================================================================
Command: USER
Function: To change current user number.
Forms: USER <usrnum>
Options: SUPRES equate controls the display of the user number in the
prompt when the user number is zero.
MAXUSR equate controls the maximum allowable user number.
NUMBASE equate defines the character that specifies a
hexadecimal number. The distribution version is set to 'H'.
Uses: This command changes the current user number. The new user
number is in decimal, but a hexadecimal number is entered by
appending an 'H'. This command has been retained for
compatibility purposes only. It is far easier to change
disk/user by typing du:.
=============================================================================
Error Messages
==============
If any error is encountered as a command line is being parsed, a
message will be printed and, for serious errors, the remainder of the
line is ignored. Below is a complete list of all ZCPR error messages.
Any error message encountered that is not on this list came from some
program other than ZCPR.
"?"
An error was detected in the command. The an item on the command
line was not what was expected. The command line is echoed up to
the position where the error was detected, as close as can be
determined, and the "?" printed. Any commands remaining on the
command the line are ignored and any $$$.SUB file erased.
"Full"
If ZCPR was attempting to load a transient program, one of two
things has gone wrong: either the program is so large that it won't
fit into the TPA or a read error was returned from the BDOS. If
ZCPR was attempting to save a file, the BDOS write call returned
failure. Either the disk or the directory is full. Any commands
remaining on the command line are ignored and any $$$.SUB file
erased.
"No File"
No file could be found matching the filename specified in the
command. This message is also be printed if the BDOS read command
returns failure. If ZCPR was looking for a transient command, any
commands remaining on the command line are ignored and any $$$.SUB
file erased.
"Name Error"
The specified filename has a user number larger than the allowable
maximum or an ambiguous filename was entered where only an
unambiguous filename is permitted. Any commands remaining on the
command line are ignored and any $$$.SUB file erased.
"Delete?"
Not really an error, but there already exists a file with the same
name as the requested new name in the REN command. Any response
except 'Y' (either case) aborts the command, any commands remaining
on the command line are ignored, and any $$$.SUB file erased.
"All?"
Not really an error, but a check to verify that all files on the
drive/user area are to be erased. Any response except 'Y' (either
case) aborts the command and any commands remaining on the command
line are ignored.
Installation Instructions
=========================
1) The first task is to determine the location of your BDOS because you
MUST set the P2DOS equate to this value. If you do not know the
location of your BDOS, use ZCPRDEMO to find it. If you do not
already have ZCPRDEMO.COM, assemble ZCPR with the TEST equate true
to make it. A bootstrap loader will be included and you can run the
.com file. This program assembles without errors using Microsoft's
M80/L80:
A>m80 =zcpr
A>l80 zcpr,zcprdemo/n/e
Other assemblers can be used, but ZCPR.MAC will probably require
editing to convert it to a form compatible. The major decision in
converting is to determine how the .PHASE pseudo is to be handled.
Probably the best solution to the .PHASE is to generate a .hex
file and load it with an offset using DDT/SID/ZSID. Consult the
"r" command in the DDT/SID/ZSID manaul.
Run ZCPRDEMO and peek at low memory:
A>zcprdemo
A<peek 0 10
0000 C3 03 F2 00 00 C3 06 E4 00 00 00 00 00 00 00 00
A<^C
Notice the prompt character has changed from a '>' to a '<'. This
tells you the special debug version of ZCPR is running. See the
debug section at the end for details. Address 0 contains a jump 3
beyond the start of the BIOS and address 5 contains a jump 6 beyond
the start of the BDOS.
Be careful if you attempt to execute a transient program from
ZCPRDEMO. Some transient programs, like NSWP, return rather than
warm boot when done. These programs don't know that ZCPRDEMO is at
address 8000H rather than just under the BDOS. If they overwrite
ZCPRDEMO, then the return is to random code. Of course, this is not
a problem when ZCPR is installed just under the BDOS.
2) You MUST edit the code to place your BDOS/P2DOS/Z80DOS/ZRDOS start
address in the P2DOS equate. Set COMLD true (and TEST false if you
set it true in step 1 above) and make ZCPR.COM. A bootstrap loader
will be included.
Assuming you successfully assemble it, just type "zcpr" to run it.
However, every time there is a warm boot, it will be replaced by
the boot track CCP. If you like what you see, place a copy on the
boot track to make it available all the time.
3) Reassemble, this time with COMLD false to make ZCPRNBLD.COM (ZCPR
No Boot LoaDer).
4) Run SYSGEN to load a copy of the boot track into memory.
B>; Sample terminal session for integrating ZCPR
B>sysgen
SYSGEN VER 2.2
SOURCE DRIVE NAME (OR RETURN TO SKIP)a
SOURCE ON A, THEN TYPE RETURN <cr>
FUNCTION COMPLETE
DESTINATION DRIVE NAME (OR RETURN TO REBOOT) <cr>
5) Run SAVE to save a track image to a file (eg: SAVE 32 BOOTFILE).
The number on the save command depends on the size of your boot
track loader; it can be as small as 31 and as large as 44. If you
have extra disk space or are not sure, play it safe and use 44.
B>save 44 cpm56.com <-- We now have a SYSGEN image of CP/M
6) Find the location of the stock CCP by peeking at the boot file. It
is normally located at address 980H in the file. Using ZCPR:
B>zcpr <-- Reload zcpr.com version
B>get 100 cpm56.com
and search for the start of the console processor:
B>peek 980
0980 C3 xx xx C3 xx xx 7F 00 43 4F 50 59 52 49 47 48
0990 54 20 ...
If you don't find the start of the CCP at 980H, don't be
discouraged. It is there, but at a higher address. Keep looking.
7) When you find the location of the CCP, patch it with the new ZCPR
image.
B>get 980 zcprnbld.com
8) Place the new file onto the boot track of a test disk, not your
original, using SYSGEN, and try it out.
B>sysgen
SYSGEN VER 2.2
SOURCE DRIVE NAME (OR RETURN TO SKIP) <cr> <-- Use memory image
DESTINATION DRIVE NAME (OR RETURN TO REBOOT)b <-- Load onto drive B
DESTINATION ON B, THEN TYPE RETURN <cr>
FUNCTION COMPLETE
DESTINATION DRIVE NAME (OR RETURN TO REBOOT) <cr>
You should now have a ZCPR system boot disk. Notice you did all
your work on drive B so you wouldn't destroy the original.
This may seem like a great number of steps, but each is only a single
CP/M command line, total time is only 5 minutes or so after you get
ZCPR to run as a .com file.
Debugging ZCPR
==============
Special provisions have been make to ease the debugging of ZCPR.
Setting the TEST equate true causes the assembler to build a version of
ZCPR that executes in the TPA. This allows the use of a debugger like
DDT, ZSID, or Z8E to load and monitor execution. To identify the debug
version, the prompt character is changed from '>' to '<' when it runs.
CPRLOC for the test version is 8000H. A bootstrap loader is included
at the beginning to move the image to this address. Do not try to set
a breakpoint until after the loader has moved ZCPR. The easiest way to
accomplish this is to single-step through the loader and then set your
breakpoints. Change the execution address to something lower if 8000H
does not leave enough space for the debugger.
A small amount of code is also added at the end of the debug version to
compute the BIOS list status and cold boot entry points at run time.
This permits the demo version to execute properly without setting the
BDOS location equate.
Patching SUBMIT.COM
===================
SUBMIT.COM is patched to run with ZCPR by the following procedure.
This is recommended if the user does not have one of the newer public
domain versions of submit. This patch simply makes SUBMIT.COM always
place the $$$.SUB file on drive A. Illustrative terminal session
follows:
A>get 100 submit.com;peek 5bb 2
05BB 00 24 <-- Patch is at 5BB Hex
A>poke 5bb 1 <-- Change 0 (default drive) to 1 (drive A)
A>peek 5b0 20 <-- Let's check just to make sure
05B0 00 00 00 00 00 00 30 30 31 20 24 01 24 24 24 20
05C0 20 20 20 20 53 55 42 00 00 00 1A 1A 1A 1A 1A 1A
A>save 5 newsubmt.com <-- Save new SUBMIT.COM file
Pretty simple, huh?
ny error message encountered that is not on this list came from some
prog

BIN
Doc/qcp27.pdf

Binary file not shown.

BIN
Doc/qdos27.pdf

Binary file not shown.

BIN
Doc/qpm27.pdf

Binary file not shown.

24
Makefile

@ -1,19 +1,19 @@
all: all:
cd Tools/unix ; make
cd Source ; make
cd Source/Images ; make
$(MAKE) --directory Tools
$(MAKE) --directory Source
clean: clean:
cd Tools/unix ; make clean
cd Source ; make clean
cd Binary ; make clean
$(MAKE) --directory Tools clean
$(MAKE) --directory Source clean
$(MAKE) --directory Binary clean
rm -f make.log
clobber:
cd Tools/unix ; make clobber
cd Source ; make clobber
cd Binary ; make clobber
rm -f typescript
clobber: clean
diff: diff:
cd Source ; make diff
$(MAKE) --directory Source diff
dist:
$(MAKE) ROM_PLATFORM=dist 2>&1 | tee make.log
$(MAKE) --directory Source clean
$(MAKE) --directory Tools clean

1250
ReadMe.md

File diff suppressed because it is too large

1221
ReadMe.txt

File diff suppressed because it is too large

49
Readme.unix

@ -1,49 +0,0 @@
this tree now contains makefiles and tools to build on Linux and MacosX
Linux is rather more thoroughly tested compared to os-x.
to get here, TASM and the propeller generation tools needed to be replaced,
and since the unix filesystem is usually case-sensitive, and CP/M and windows
are not, the cpm tools were made case-insensitive.
TASM was replaced with uz80as, which implements a subset of TASM and fixes some
bugs. however, I needed to add some functionality to make it build the sources
as they exist in this tree. in particular, one thing to be very careful of is
that TASM is not entirely consistent with respect to the .DS directive.
it's usually a bad idea to mix .DS, .FILL, .DB with .ORG.
.DS n is best thought of as .ORG $ + n
.ORG changes the memory pointer, but does not change the file output point.
it works a lot more like M80, SLR* .phase
it assumes that you have some standard system tools and libraries installed
specifically: gcc, gnu make, libncurses
to build:
cd to the top directory and type make.
heavy use is made of make's include facility and pattern rules.
the master rule set is in Tools/Makefile.inc. changes here will affect
almost every Makefile, and where exceptions are needed, the overrides are
applied in the lower Makefiles.
these tools can run a windows-linux regression test, where all the binaries are
compared to a baseline windows build.
Credit:
uz80as was written by Jorge Giner Cordero, jorge.giner@hotmail.com,
and the original source can be found at https://github.com/jorgicor/uz80as
the propeller tools use bstc and openspin, parallax tools from
http://www.fnarfbargle.com/bst.html https://github.com/parallaxinc/OpenSpin
note that bst is not open source or even currently maintained, so I could
not generate a version for 64 bit osx.
cpmtools were the most current I could find, and it has been hacked to do
case-insensitivity. these are not marked, and are not extensive.
zx is from distributed version, and also has local hacks for case insensitivity.
both zx and cpmtools ship with an overly complicated makefile generation system
and this is ignored.
this whole linux build framework is the work of Curt Mayer, curt@zen-room.org.
use it for whatever you like; this is not my day job.

1899
Source/Apps/Assign.asm

File diff suppressed because it is too large

56
Source/Apps/Build.cmd

@ -4,45 +4,47 @@ setlocal
set TOOLS=../../Tools set TOOLS=../../Tools
set APPBIN=..\..\Binary\Apps set APPBIN=..\..\Binary\Apps
set PATH=%TOOLS%\tasm32;%TOOLS%\zx;%PATH%
set PATH=%TOOLS%\tasm32;%TOOLS%\zxcc;%PATH%
set TASMTABS=%TOOLS%\tasm32 set TASMTABS=%TOOLS%\tasm32
set ZXBINDIR=%TOOLS%/cpm/bin/
set ZXLIBDIR=%TOOLS%/cpm/lib/
set ZXINCDIR=%TOOLS%/cpm/include/
call :asm SysCopy || goto :eof
call :asm Assign || goto :eof
call :asm Format || goto :eof
call :asm Talk || goto :eof
call :asm Mode || goto :eof
call :asm RTC || goto :eof
call :asm Timer || goto :eof
call :asm180 IntTest || goto :eof
zx Z80ASM -SYSGEN/F
zx MAC SURVEY.ASM -$PO
zx MLOAD25 -SURVEY.COM=SURVEY.HEX
setlocal & cd XM && call Build || exit /b 1 & endlocal
setlocal & cd FDU && call Build || exit /b 1 & endlocal
setlocal & cd Tune && call Build || exit /b 1 & endlocal
setlocal & cd FAT && call Build || exit /b 1 & endlocal
copy *.com %APPBIN%\
set CPMDIR80=%TOOLS%/cpm/
call :asm syscopy || exit /b
call :asm assign || exit /b
call :asm format || exit /b
call :asm talk || exit /b
call :asm mode || exit /b
call :asm rtc || exit /b
call :asm timer || exit /b
call :asm rtchb || exit /b
zxcc Z80ASM -SYSGEN/F || exit /b
pushd XM && call Build || exit /b & popd
pushd FDU && call Build || exit /b & popd
pushd Tune && call Build || exit /b & popd
pushd FAT && call Build || exit /b & popd
pushd Test && call Build || exit /b & popd
pushd ZMP && call Build || exit /b & popd
pushd ZMD && call Build || exit /b & popd
pushd Dev && call Build || exit /b & popd
pushd VGM && call Build || exit /b & popd
pushd cpuspd && call Build || exit /b & popd
pushd Survey && call Build || exit /b & popd
copy *.com %APPBIN%\ || exit /b
goto :eof goto :eof
:asm :asm
echo. echo.
echo Building %1... echo Building %1...
tasm -t80 -g3 -fFF %1.asm %1.com %1.lst
tasm -t80 -g3 -fFF %1.asm %1.com %1.lst || exit /b
goto :eof goto :eof
:asm180 :asm180
echo. echo.
echo Building %1... echo Building %1...
tasm -t180 -g3 -fFF %1.asm %1.com %1.lst
tasm -t180 -g3 -fFF %1.asm %1.com %1.lst || exit /b
goto :eof goto :eof

15
Source/Apps/Clean.cmd

@ -7,7 +7,14 @@ if exist *.lst del *.lst
if exist *.hex del *.hex if exist *.hex del *.hex
if exist *.prn del *.prn if exist *.prn del *.prn
setlocal & cd XM && call Clean || exit /b 1 & endlocal
setlocal & cd FDU && call Clean || exit /b 1 & endlocal
setlocal & cd Tune && call Clean || exit /b 1 & endlocal
setlocal & cd FAT && call Clean || exit /b 1 & endlocal
pushd XM && call Clean || exit /b 1 & popd
pushd FDU && call Clean || exit /b 1 & popd
pushd Tune && call Clean || exit /b 1 & popd
pushd FAT && call Clean || exit /b 1 & popd
pushd Test && call Clean || exit /b 1 & popd
pushd ZMP && call Clean || exit /b 1 & popd
pushd ZMD && call Clean || exit /b 1 & popd
pushd Dev && call Clean || exit /b 1 & popd
pushd VGM && call Clean || exit /b 1 & popd
pushd cpuspd && call Clean || exit /b 1 & popd
pushd Survey && call Clean || exit /b 1 & popd

14
Source/Apps/Dev/Build.cmd

@ -0,0 +1,14 @@
@echo off
setlocal
set TOOLS=../../../Tools
set PATH=%TOOLS%\tasm32;%PATH%
set TASMTABS=%TOOLS%\tasm32
echo Building Dev...
tasm -t80 -g3 -fFF dev.asm dev.com %dev.lst || exit /b
copy /Y dev.com ..\..\..\Binary\Apps\ || exit /b
rem copy /Y *.ovr ..\..\..\Binary\Apps\ || exit /b
rem copy /Y *.hlp ..\..\..\Binary\Apps\ || exit /b
rem copy /Y *.doc ..\..\..\Binary\Apps\ || exit /b

7
Source/Apps/Dev/Clean.cmd

@ -0,0 +1,7 @@
@echo off
setlocal
if exist dev.com del dev.com
if exist *.hex del *.hex
if exist *.lst del *.lst
if exist *.zip del *.zip

10
Source/Apps/Dev/Makefile

@ -0,0 +1,10 @@
OBJECTS = dev.com
#DOCS = dev.txt
DEST = ../../../Binary/Apps
DOCDEST = ../../../Binary/Apps
TOOLS = ../../../Tools
include $(TOOLS)/Makefile.inc
%.com: USETASM=1

1
Source/Apps/Dev/ReadMe.txt

@ -0,0 +1 @@
THE DEV DIRECTORY IS A SKELETON DIRECTORY TO AID SETTING UP A BUILD PROCESS FOR A NEW PROGRAM

32
Source/Apps/Dev/dev.asm

@ -0,0 +1,32 @@
;===============================================================================
; Dev - Developement Stub
;===============================================================================
;
; AUTHOR:
;
; Usage:
;
;_______________________________________________________________________________
;
; Change Log:
;
;_______________________________________________________________________________
;
; ToDo:
;
;_______________________________________________________________________________
;
;===============================================================================
; Definitions
;===============================================================================
;
;
;===============================================================================
; Code Section
;===============================================================================
;
;
.org $100
ret
.end

2
Source/Apps/FAT/Build.cmd

@ -4,4 +4,4 @@ setlocal
REM FAT.com is currently distributed as a binary application, so REM FAT.com is currently distributed as a binary application, so
REM it is not built here. REM it is not built here.
copy /Y FAT.com ..\..\..\Binary\Apps\
copy /Y fat.com ..\..\..\Binary\Apps\ || exit /b

BIN
Source/Apps/FAT/FAT.com

Binary file not shown.

4
Source/Apps/FAT/Makefile

@ -1,5 +1,5 @@
OBJECTS = FAT.com
NODELETE = FAT.com
OBJECTS = fat.com
NODELETE = fat.com
DEST = ../../../Binary/Apps DEST = ../../../Binary/Apps
TOOLS=../../../Tools TOOLS=../../../Tools

9
Source/Apps/FAT/ReadMe.txt

@ -1,7 +1,7 @@
RomWBW HBIOS CP/M FAT Utility ("FAT.COM") RomWBW HBIOS CP/M FAT Utility ("FAT.COM")
Author: Wayne Warthen Author: Wayne Warthen
Updated: 11-Oct-2019
Updated: 12-Apr-2021
Application to manipulate and exchange files with a FAT (DOS) Application to manipulate and exchange files with a FAT (DOS)
filesystem. Runs on any HBIOS hosted CP/M implementation. filesystem. Runs on any HBIOS hosted CP/M implementation.
@ -47,7 +47,7 @@ NOTES:
"C:README.TXT" refers to CP/M file README.TXT on CP/M drive C "C:README.TXT" refers to CP/M file README.TXT on CP/M drive C
"README.TXT" refers to CP/M file README.TXT on current CP/M drive "README.TXT" refers to CP/M file README.TXT on current CP/M drive
- Files with SYS, HIDDEN, or R/O only attributes are not given
- FAT files with SYS, HIDDEN, or R/O only attributes are not given
any special treatment. Such files are found and processed any special treatment. Such files are found and processed
like any other file. However, any attempt to write to a like any other file. However, any attempt to write to a
read-only file will fail and the application will abort. read-only file will fail and the application will abort.
@ -70,7 +70,7 @@ BUILD NOTES:
- Application is based on FatFs. FatFs source is included. - Application is based on FatFs. FatFs source is included.
- SDCC compiler is required to build (v3.9.0 known working).
- SDCC compiler is required to build (v4.0.0 known working).
- ZX CP/M emulator is required to build (from RomWBW distribution). - ZX CP/M emulator is required to build (from RomWBW distribution).
@ -88,6 +88,8 @@ TO DO:
- Do something intelligent with R/O and SYS files on FAT - Do something intelligent with R/O and SYS files on FAT
- Support UNA
HISTORY: HISTORY:
2-May-2019: v0.9 (beta) initial release 2-May-2019: v0.9 (beta) initial release
7-May-2019: v0.9.1 (beta) added REN and DEL 7-May-2019: v0.9.1 (beta) added REN and DEL
@ -98,4 +100,5 @@ HISTORY:
10-Oct-2019: v0.9.6 (beta) added FORMAT 10-Oct-2019: v0.9.6 (beta) added FORMAT
11-Oct-2019: v0.9.7 (beta) fix FORMAT to use existing partition table entries 11-Oct-2019: v0.9.7 (beta) fix FORMAT to use existing partition table entries
add attributes to directory listing add attributes to directory listing
12-Apr-2021: v0.9.8 (beta) support CP/NET drives

BIN
Source/Apps/FAT/fat.com

Binary file not shown.

8
Source/Apps/FDU/Build.cmd

@ -5,9 +5,7 @@ set TOOLS=../../../Tools
set PATH=%TOOLS%\tasm32;%PATH% set PATH=%TOOLS%\tasm32;%PATH%
set TASMTABS=%TOOLS%\tasm32 set TASMTABS=%TOOLS%\tasm32
tasm -t80 -b -fFF FDU.asm FDU.com FDU.lst
tasm -t80 -b -fFF fdu.asm fdu.com fdu.lst || exit /b
if errorlevel 1 goto :eof
copy /Y FDU.com ..\..\..\Binary\Apps\
copy /Y FDU.txt ..\..\..\Doc\
copy /Y fdu.com ..\..\..\Binary\Apps\ || exit /b
copy /Y fdu.doc ..\..\..\Binary\Apps\ || exit /b

4613
Source/Apps/FDU/FDU.asm

File diff suppressed because it is too large

514
Source/Apps/FDU/FDU.txt

@ -1,514 +0,0 @@
================================================================
Floppy Disk Utility (FDU) v5.3 for RetroBrew Computers
Disk IO / Zeta / Dual-IDE / N8 / RC2014 / SmallZ80 / Dyno
================================================================
Updated January 5, 2020
by Wayne Warthen (wwarthen@gmail.com)
Application to test the hardware functionality of the Floppy
Disk Controller (FDC) on the ECB DISK I/O, DISK I/O V3, ZETA
SBC, Dual IDE w/ Floppy, or N8 board.
The intent is to provide a testbed that allows direct testing
of all possible media types and modes of access. The
application supports read, write, and format by sector, track,
and disk as well as a random read/write test.
The application supports access modes of polling, interrupt,
INT/WAIT, and DRQ/WAIT. At present, it supports 3.5" media at
DD (720KB) and HD (1.44MB) capacities. It also now supports
5.25" media (720KB and 1.2MB) and 8" media (1.11MB) as well.
Additional media will be added when I have time and access to
required hardware. Not all modes are supported on all
platforms and some modes are experimental in all cases.
In many ways this application is merely reinventing the wheel
and performs functionality similar to existing applications,
but I have not seen any other applications for RetroBrew
Computers hardware that provide this range of functionality.
While the application is now almost entirely new code, I would
like to acknowledge that much was derived from the previous
work of Andrew Lynch and Dan Werner. I also want to credit
Sergio Gimenez with testing the 5.25" drive support and Jim
Harre with testing the 8" drive support. Support for Zeta 2
comes from Segey Kiselev. Thanks!
General Usage
-------------
In general, usage is self explanatory. At invocation, you
must select the floppy disk controller (FDC) that you are
using. Subsequently, the main menu allows you to set the
unit, media, and mode to test. These settings MUST match your
situation. Read, write, format, and verify functions are
provided. A sub-menu will allow you to choose sector, track,
disk, or random tests.
The verify function requires a little explanation. It will
take the contents of the current in-memory disk buffer, save
it, and compare it to the selected sectors. So, you must
ensure that the sectors to be verified already have been
written with the same pattern as the buffer contains. I
typically init the buffer to a pattern, write the pattern to
the entire disk, then verify the entire disk.
Another submenu is provided for FDC commands. This sub-menu
allows you to send low-level commands directly to FDC. You
*must* know what you are doing to use this sub-menu. For
example, in order to read a sector using this sub-menu, you
will need to perform specify, seek, sense int, and read
commands specifying correct values (nothing is value checked
in this menu).
Required Hardware/BIOS
----------------------
Of course, the starting point is to have a supported hardware
configuration. The following Z80 / Z180 based CPU boards are
supported:
- SBC V1/2
- Zeta
- Zeta 2
- N8
- Mark IV
- RC2014 w/ SMC
- RC2014 w/ WDC
- SmallZ80
- Dyno
You must be using either a RomWBW or UBA based OS version.
You must have one of the following floppy disk controllers:
- Disk IO ECB Board FDC
- Disk IO 3 ECB Board FDC
- Dual-IDE ECB Board FDC
- Zeta SBC onboard FDC
- Zeta 2 SBC onboard FDC
- N8 SBC onboard FDC
- RC2014 Scott Baker SMC-based Floppy Module
- RC2014 Scott Baker WDC-based Floppy Module
Finally, you will need a floppy drive connected via an
appropriate cable:
Disk IO - no twist in cable, drive unit 0/1 must be selected by jumper on drive
DISK IO 3, Zeta, Zeta 2, RC2014, Dyno - cable with twist, unit 0 after twist, unit 1 before twist
DIDE, N8, Mark IV, SmallZ80 - cable with twist, unit 0 before twist, unit 1 after twist
Note that FDU does not utilize your systems ROM or OS to
access the floppy system. FDU interacts directly with
hardware. Upon exit, you may need to reset your OS to get the
floppy system back into a state that is expected.
The Disk I/O should be jumpered as follows:
J1: depends on use of interrupt modes (see interrupt modes below)
J2: pins 1-2, & 3-4 jumpered
J3: hardware dependent timing for DMA mode (see DMA modes below)
J4: pins 2-3 jumpered
J5: off
J6: pins 2-3 jumpered
J7: pins 2-3 jumpered
J8: off
J9: off
J10: off
J11: off
J12: off
Note that J1 can be left on even when not using interrupt
modes. As long as the BIOS is OK with it, that is fine. Note
also that J3 is only relevant for DMA modes, but also can be
left in place when using other modes.
The Disk I/O 3 board should be jumpered at the default settings:
JP2: 3-4
JP3: 1-2 for int mode support, otherwise no jumper
JP4: 1-2, 3-4
JP5: 1-2
JP6: 1-2
JP7: 1-2, 3-4
Zeta & Zeta 2 do not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
The Dual-IDE board should be jumpered as follows:
K3 (DT/R or /RD): /RD
P5 (bd ID): 1-2, 3-4 (for $20-$3F port range)
There are no specific N8 jumper settings, but the default
I/O range starting at $80 is assumed in the published code.
The RC2014 Scott Baker SMC-based floppy module should be jumpered
for I/O base address 0x50 (SV1: 11-12), JP1 (TS) shorted,
JP2 (/FAULT) shorted, JP3 (MINI): 2-3, JP4 (/DC/RDY): 2-3.
The RC2014 Scott Baker WDC-based floppy module should be jumpered
for I/O base address 0x50 (SV1: 11-12), JP1 (/DACK): 1-2,
JP2 (TC): 2-3.
SmallZ80 does not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
Dyno does not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
Modes of Operation
------------------
You can select the following test modes. Please refer to the
chart that follows to determine which modes should work with
combinations of Z80 CPU speed and media format.
WARNING: In general, only the polling mode is considered fully
reliable. The other modes are basically experimental and
should only be used if you know exactly what you are doing.
Polling: Traditional polled input/output. Works well and very
reliable with robust timeouts and good error recovery. Also,
the slowest performance which precludes it from being used
with 1.44MB floppy on a 4MHz Z80. This is definitely the mode
you want to get working before any others. It does not require
J1 (interrupt enable) on DISK I/O and does not care about the
setting of J3.
Interrupt: Relies on FDC interrupts to determine when a byte
is ready to be read/written. It does *not* implement a
timeout during disk operations. For example, if there is no
disk in the drive, this mode will just hang until a disk is
inserted. This mode *requires* that the host has interrupts
active using interrupt mode 1 (IM1) and interrupts attached to
the FDC controller. The BIOS must be configured to handle
these interrupts safely.
Fast Interrupt: Same as above, but sacrifices additional
reliability for faster operation. This mode will allow a
1.44MB floppy to work with a 4MHz Z80 CPU. However, if any
errors occur (even a transient read error which is not
unusual), this mode will hang. The same FDC interrupt
requirements as above are required.
INT/WAIT: Same as Fast Interrupt, but uses CPU wait instead of
actual interrupt. This mode is exclusive to the original Disk
IO board. It is subject to all the same issues as Fast
Interrupt, but does not need J1 shorted. J3 is irrelevant.
DRQ/WAIT: Uses pseudo DMA to handle input/output. Does not
require that interrupts (J1) be enabled on the DISK I/O.
However, it is subject to all of the same reliability issues
as "Fast Interrupt". This mode is exclusive to the original
Disk IO board. At present, the mode is *not* implemented!
The chart below attempts to describe the combinations that
work for me. By far, the most reliable mode is Polling, but
it requires 8MHz CPU for HD disks.
DRQ/WAIT --------------------------------+
INT/WAIT -----------------------------+ |
Fast Interrupt --------------------+ | |
Interrupt ----------------------+ | | |
Polling ---------------------+ | | | |
| | | | |
CPU Speed --------------+ | | | | |
| | | | | |
| | | | | |
3.5" DD (720K) ------ 4MHz Y Y Y Y X
8MHz+ Y Y Y Y X
3.5" HD (1.44M) ----- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
5.25" DD (360K) ----- 4MHz Y Y Y Y X
8MHz+ Y Y Y Y X
5.25" HD (1.2M) ----- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
8" DD (1.11M) ------- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
Y = Yes, works
N = No, does not work
X = Experimental, probably won't work
Tracing
-------
Command/result activity to/from the FDC will be written out if
the trace setting is changed from '00' to '01' in setup.
Additionally, if a command failure is detected on any command,
that specific comand and results are written regardless of the
trace setting.
The format of the line written is:
<OPERATION>: <COMMAND BYTES> --> <RESULT BYTES> [<RESULT>]
For example, this is the output of a normal read operation:
READ: 46 01 00 00 01 02 09 1B FF --> 01 00 00 00 00 02 02 [OK]
Please refer to the i8272 data sheet for information on the
command and result bytes.
Note that the sense interrupt command can return a non-OK
result. This is completely normal in some cases. It is
necessary to "poll" the drive for seek status using sense
interrupt. If there is nothing to report, then the result
will be INVALID COMMAND. Additionally, during a recalibrate
operation, it may be necessary to issue the command twice
because the command will only step the drive 77 times looking
for track 0, but the head may be up to 80 tracks away. In
this case, the first recalibrate fails, but the second should
succeed. Here is what this would look like if trace is turned
on:
RECALIBRATE: 07 01 --> <EMPTY> [OK]
SENSE INTERRUPT: 08 --> 80 [INVALID COMMAND]
...
...
...
SENSE INTERRUPT: 08 --> 80 [INVALID COMMAND]
SENSE INTERRUPT: 08 --> 71 00 [ABNORMAL TERMINATION]
RECALIBRATE: 07 01 --> <EMPTY> [OK]
SENSE INTERRUPT: 08 --> 21 00 [OK]
Another example is when the FDC has just been reset. In this
case, you will see up to 4 disk change errors. Again these
are not a real problem and to be expected.
When tracing is turned off, the application tries to be
intelligent about error reporting. The specific errors from
sense interrupt documented above will be suppressed because
they are not a real problem. All other errors will be
displayed.
Error Handling
--------------
There is no automated error retry logic. This is very
intentional since the point is to expose the controller and
drive activity. Any error detected will result in a prompt to
abort, retry, or continue. Note that some number of errors is
considered normal for this technology. An occasional error
would not necessarily be considered a problem.
CPU Speed
---------
Starting with v5.0, the application adjusts it's timing loops
to the actual system CPU speed by querying the BIOS for the
current CPU speed.
Interleave
----------
The format command now allows the specification of a sector
interleave. It is almost always the case that the optimal
interleave will be 2 (meaning 2:1).
360K Media
----------
The 360K media definition should work well for true 360K
drives. However, it will generally not work with 1.2M
drives. This is because these drives spin at 360RPM instead
of the 300RPM speed of true 360K drives. Additionally, 1.2M
drives are 80 tracks and 360K drives are 40 tracks and, so
far, there is no mechanism in FD to "double step" as a way to
use 40 track media in 80 track drives.
With this said, it is possible to configure some 1.2M 5.25"
drives to automatically spin down to 300RPM based on a density
select signal (DENSEL). This signal is asserted by FD for
360K media, so IF you have configured your drive to react to
this signal correctly, you will be able to use the 360K media
defintion. Most 1.2M 5.25" drives are NOT configured this way
by default. TEAC drives are generally easy to modify and have
been tested by the author and do work in this manner. Note
that this does not address the issue of double stepping above;
you will just be using the first 40 of 80 tracks.
Support
-------
I am happy to answer questions as fast and well as I am able.
Best contact is wwarthen@gmail.com or post something on the
RetroBrew Computers Forum
https://www.retrobrewcomputers.org/forum/.
Changes
-------
WW 8/12/2011
Removed call to pulse TC in the FDC initialization after
determining that it periodically caused the FDC to write bad
sectors. I am mystified by this, but definitely found it to
be true. Will revisit at some point -- probably a timing
issue between puslsing TC and whatever happens next.
Non-DMA mode was being set incorrectly for FAST-DMA mode. It
was set for non-DMA even though we were doing DMA. It is
interesting that it worked fine anyway. Fixed it anyway.
DIO_SETMEDIA was not clearing DCD_DSKRDY as it should. Fixed.
WW 8/26/2011: v1.1
Added support for Zeta. Note that INT/WAIT and DRQ/WAIT are
not available on Zeta. Note that Zeta provides the ability to
perform a reset of the FDC independent of a full CPU reset.
This is VERY useful and the FDC is reset anytime a drive reset
is required.
Added INT/WAIT support.
WW 8/28/2011: V1.2
All changes in this version are Zeta specific. Fixed FDC
reset logic and motor status display for Zeta (code from
Sergey).
Modified Zeta disk change display to include it in the command
output line. This makes more sense because a command must be
issued to select the desired drive first. You can use the
SENSE INT command id you want to check the disk change value
at any time. It will also be displayed with any other command
output display.
WW 9/1/2011: V1.3
Added CPUFREQ configuration setting to tune delays based on
cpu speed. The build app is set for 8MHz which also seems to
work well for 4MHz CPU's. Faster CPU speeds will probably
require tuning this setting.
WW 9/5/2011: V1.4
Changed the polling execution routines to utilize CPUFREQ
variable to optimize timeout counter. Most importantly, this
should allow the use of faster CPUs (like 20MHz).
WW 9/19/2011: V1.5
Zeta changes only. Added a call to FDC RESET after any
command failure. This solves an issue where the drive remains
selected if a command error occurs. Also added FDC RESET to
FDC CONTROL menu.
WW 10/7/2011: V2.0
Added support for DIDE. Only supports polling IO and it does
not appear any other modes are possible given the hardware
constraints.
WW 10/13/2011: V2.1
Modified to support N8. N8 is essentially identical to Dual
IDE. The only real change is the IO addresses. In theory, I
should be able to support true DMA on N8 and will work on that.
WW 10/20/2011: v2.2
I had some problems with the results being read were sometimes
missing a byte. Fixed this by taking a more strict approach
to watching the MSR for the exact bits that are expected.
WW 10/22/2011: V2.3
After spending a few days trying to track down an intermittent
data corruption issue with my Dual IDE board, I added a verify
function. This helped me isolate the problem very nicely
(turned out to be interference from the bus monitor).
WW 11/25/2011: V2.4
Preliminary support for DISKIO V3. Basically just assumed
that it operates just like the Zeta. Needs to be verified
with real hardware as soon as I can.
WW 1/9/2012: V2.5
Modified program termination to use CP/M reset call so that a
warm start is done and all drives are logged out. This is
important because media may have been formatted during the
program execution.
WW 2/6/2012: v2.6
Added support for 5.25" drives as tested by Sergio.
WW 4/5/2012: v2.7
Added support for 8" drives as tested by Jim Harre.
WW 4/6/2012: v2.7a
Fixed issue with media selection menu to remove duplicate
entries.
WW 4/8/2012: v2.7b
Corrected the handling of the density select signal.
WW 5/22/2012: v2.8
Added new media definitions (5.25", 320K).
WW 6/1/2012: v2.9
Added interleave capability on format.
WW 6/5/2012: v3.0
Documentation cleanup.
WW 7/1/2012: v3.1
Modified head load time (HLT) for 8" media based on YD-180
spec. Now set to 50ms.
WW 6/17/2013: v3.2
Cleaned up SRT, HLT, and HUT values.
SK 2/10/2015: v3.3
Added Zeta SBC v2 support (Sergey Kiselev)
WW 3/25/2015: v4.0
Renamed from FDTST --> FD
WW 9/2/2017: v5.0
Renamed from FD to FDU.
Added runtime selection of FDC hardware.
Added runtime timing adjustment.
WW 12/16/2017: v5.1
Improved polling version of read/write to fix occasional overrun errors.
WW 1/8/2018: v5.2
Added support for RC2014 hardware:
- Scott Baker SMC 9266 FDC module
- Scott Baker WDC 37C65 FDC module
WW 9/5/2018: v5.3
- Removed use of pulsing TC to end R/W operations after one sector and
instead set EOT = R (sector number) so that after desired sector is
read, R/W stops with end of cylinder error which is a documented
method for controling number of sectors R/W. This specific termination
condition is no longer considered an error, but a successful end of
operation.
- Added support for SmallZ80
WW 5/1/2020: v5.4
- Added support for Dyno (based on work by Steve Garcia)

6
Source/Apps/FDU/Makefile

@ -1,7 +1,7 @@
OBJECTS = FDU.com
DOCS = FDU.txt
OBJECTS = fdu.com
DOCS = fdu.doc
DEST = ../../../Binary/Apps DEST = ../../../Binary/Apps
DOCDEST = ../../../Doc
DOCDEST = ../../../Binary/Apps
TOOLS = ../../../Tools TOOLS = ../../../Tools
include $(TOOLS)/Makefile.inc include $(TOOLS)/Makefile.inc

4757
Source/Apps/FDU/fdu.asm

File diff suppressed because it is too large

535
Source/Apps/FDU/fdu.doc

@ -0,0 +1,535 @@
================================================================
Floppy Disk Utility (FDU) v5.3 for RetroBrew Computers
Disk IO / Zeta / Dual-IDE / N8 / RCBus / SmallZ80 / Dyno
================================================================
Updated January 5, 2020
by Wayne Warthen (wwarthen@gmail.com)
Application to test the hardware functionality of the Floppy
Disk Controller (FDC) on the ECB DISK I/O, DISK I/O V3, ZETA
SBC, Dual IDE w/ Floppy, or N8 board.
The intent is to provide a testbed that allows direct testing
of all possible media types and modes of access. The
application supports read, write, and format by sector, track,
and disk as well as a random read/write test.
The application supports access modes of polling, interrupt,
INT/WAIT, and DRQ/WAIT. At present, it supports 3.5" media at
DD (720KB) and HD (1.44MB) capacities. It also now supports
5.25" media (720KB and 1.2MB) and 8" media (1.11MB) as well.
Additional media will be added when I have time and access to
required hardware. Not all modes are supported on all
platforms and some modes are experimental in all cases.
In many ways this application is merely reinventing the wheel
and performs functionality similar to existing applications,
but I have not seen any other applications for RetroBrew
Computers hardware that provide this range of functionality.
While the application is now almost entirely new code, I would
like to acknowledge that much was derived from the previous
work of Andrew Lynch and Dan Werner. I also want to credit
Sergio Gimenez with testing the 5.25" drive support and Jim
Harre with testing the 8" drive support. Support for Zeta 2
comes from Sergey Kiselev. Thanks!
General Usage
-------------
In general, usage is self explanatory. At invocation, you
must select the floppy disk controller (FDC) that you are
using. Subsequently, the main menu allows you to set the
unit, media, and mode to test. These settings MUST match your
situation. Read, write, format, and verify functions are
provided. A sub-menu will allow you to choose sector, track,
disk, or random tests.
The verify function requires a little explanation. It will
take the contents of the current in-memory disk buffer, save
it, and compare it to the selected sectors. So, you must
ensure that the sectors to be verified already have been
written with the same pattern as the buffer contains. I
typically init the buffer to a pattern, write the pattern to
the entire disk, then verify the entire disk.
Another submenu is provided for FDC commands. This sub-menu
allows you to send low-level commands directly to FDC. You
*must* know what you are doing to use this sub-menu. For
example, in order to read a sector using this sub-menu, you
will need to perform specify, seek, sense int, and read
commands specifying correct values (nothing is value checked
in this menu).
Required Hardware/BIOS
----------------------
Of course, the starting point is to have a supported hardware
configuration. The following Z80 / Z180 based CPU boards are
supported:
- SBC V1/2
- Zeta
- Zeta 2
- N8
- Mark IV
- RCBus
- SmallZ80
- Dyno
- MBC
You must be using either a RomWBW or UBA based OS version.
You must have one of the following floppy disk controllers:
- Disk IO ECB Board FDC
- Disk IO 3 ECB Board FDC
- Dual-IDE ECB Board FDC
- Zeta SBC onboard FDC
- Zeta 2 SBC onboard FDC
- N8 SBC onboard FDC
- RCBus Scott Baker SMC-based Floppy Module
- RCBus Scott Baker WDC-based Floppy Module
- SmallZ80 FDC
- Dyno FDC
- MBC FDC
Finally, you will need a floppy drive connected via an
appropriate cable:
Disk IO - no twist in cable, drive unit 0/1 must be selected by jumper on drive
DISK IO 3, Zeta, Zeta 2, RCBus, Dyno - cable with twist, unit 0 after twist, unit 1 before twist
DIDE, N8, Mark IV, SmallZ80 - cable with twist, unit 0 before twist, unit 1 after twist
Note that FDU does not utilize your systems ROM or OS to
access the floppy system. FDU interacts directly with
hardware. Upon exit, you may need to reset your OS to get the
floppy system back into a state that is expected.
The Disk I/O should be jumpered as follows:
J1: depends on use of interrupt modes (see interrupt modes below)
J2: pins 1-2, & 3-4 jumpered
J3: hardware dependent timing for DMA mode (see DMA modes below)
J4: pins 2-3 jumpered
J5: off
J6: pins 2-3 jumpered
J7: pins 2-3 jumpered
J8: off
J9: off
J10: off
J11: off
J12: off
Note that J1 can be left on even when not using interrupt
modes. As long as the BIOS is OK with it, that is fine. Note
also that J3 is only relevant for DMA modes, but also can be
left in place when using other modes.
The Disk I/O 3 board should be jumpered at the default settings:
JP2: 3-4
JP3: 1-2 for int mode support, otherwise no jumper
JP4: 1-2, 3-4
JP5: 1-2
JP6: 1-2
JP7: 1-2, 3-4
Zeta & Zeta 2 do not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
The Dual-IDE board should be jumpered as follows:
K3 (DT/R or /RD): /RD
P5 (bd ID): 1-2, 3-4 (for $20-$3F port range)
There are no specific N8 jumper settings, but the default
I/O range starting at $80 is assumed in the published code.
The RCBus Scott Baker SMC-based floppy module should be jumpered
for I/O base address 0x50 (SV1: 11-12), JP1 (TS) shorted,
JP2 (/FAULT) shorted, JP3 (MINI): 2-3, JP4 (/DC/RDY): 2-3.
The RCBus Scott Baker WDC-based floppy module should be jumpered
for I/O base address 0x50 (SV1: 11-12), JP1 (/DACK): 1-2,
JP2 (TC): 2-3.
The RCBus FDC by Alan Cox (Etched Pixels) needs to be strapped
for base I/O address 0x48.
SmallZ80 does not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
Dyno does not have any relevant jumper settings. The
hardwired I/O ranges are assumed in the code.
The MBC FDC is expected to be strapped to use neither INT nor NMI. It
is also not expected to use DMA.
Modes of Operation
------------------
You can select the following test modes. Please refer to the
chart that follows to determine which modes should work with
combinations of Z80 CPU speed and media format.
WARNING: In general, only the polling mode is considered fully
reliable. The other modes are basically experimental and
should only be used if you know exactly what you are doing.
Polling: Traditional polled input/output. Works well and very
reliable with robust timeouts and good error recovery. Also,
the slowest performance which precludes it from being used
with 1.44MB floppy on a 4MHz Z80. This is definitely the mode
you want to get working before any others. It does not require
J1 (interrupt enable) on DISK I/O and does not care about the
setting of J3.
Interrupt: Relies on FDC interrupts to determine when a byte
is ready to be read/written. It does *not* implement a
timeout during disk operations. For example, if there is no
disk in the drive, this mode will just hang until a disk is
inserted. This mode *requires* that the host has interrupts
active using interrupt mode 1 (IM1) and interrupts attached to
the FDC controller. The BIOS must be configured to handle
these interrupts safely.
Fast Interrupt: Same as above, but sacrifices additional
reliability for faster operation. This mode will allow a
1.44MB floppy to work with a 4MHz Z80 CPU. However, if any
errors occur (even a transient read error which is not
unusual), this mode will hang. The same FDC interrupt
requirements as above are required.
INT/WAIT: Same as Fast Interrupt, but uses CPU wait instead of
actual interrupt. This mode is exclusive to the original Disk
IO board. It is subject to all the same issues as Fast
Interrupt, but does not need J1 shorted. J3 is irrelevant.
DRQ/WAIT: Uses pseudo DMA to handle input/output. Does not
require that interrupts (J1) be enabled on the DISK I/O.
However, it is subject to all of the same reliability issues
as "Fast Interrupt". This mode is exclusive to the original
Disk IO board. At present, the mode is *not* implemented!
The chart below attempts to describe the combinations that
work for me. By far, the most reliable mode is Polling, but
it requires 8MHz CPU for HD disks.
DRQ/WAIT --------------------------------+
INT/WAIT -----------------------------+ |
Fast Interrupt --------------------+ | |
Interrupt ----------------------+ | | |
Polling ---------------------+ | | | |
| | | | |
CPU Speed --------------+ | | | | |
| | | | | |
| | | | | |
3.5" DD (720K) ------ 4MHz Y Y Y Y X
8MHz+ Y Y Y Y X
3.5" HD (1.44M) ----- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
5.25" DD (360K) ----- 4MHz Y Y Y Y X
8MHz+ Y Y Y Y X
5.25" HD (1.2M) ----- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
8" DD (1.11M) ------- 4MHz N N Y Y X
8MHz+ Y Y Y Y X
Y = Yes, works
N = No, does not work
X = Experimental, probably won't work
Tracing
-------
Command/result activity to/from the FDC will be written out if
the trace setting is changed from '00' to '01' in setup.
Additionally, if a command failure is detected on any command,
that specific comand and results are written regardless of the
trace setting.
The format of the line written is:
<OPERATION>: <COMMAND BYTES> --> <RESULT BYTES> [<RESULT>]
For example, this is the output of a normal read operation:
READ: 46 01 00 00 01 02 09 1B FF --> 01 00 00 00 00 02 02 [OK]
Please refer to the i8272 data sheet for information on the
command and result bytes.
Note that the sense interrupt command can return a non-OK
result. This is completely normal in some cases. It is
necessary to "poll" the drive for seek status using sense
interrupt. If there is nothing to report, then the result
will be INVALID COMMAND. Additionally, during a recalibrate
operation, it may be necessary to issue the command twice
because the command will only step the drive 77 times looking
for track 0, but the head may be up to 80 tracks away. In
this case, the first recalibrate fails, but the second should
succeed. Here is what this would look like if trace is turned
on:
RECALIBRATE: 07 01 --> <EMPTY> [OK]
SENSE INTERRUPT: 08 --> 80 [INVALID COMMAND]
...
...
...
SENSE INTERRUPT: 08 --> 80 [INVALID COMMAND]
SENSE INTERRUPT: 08 --> 71 00 [ABNORMAL TERMINATION]
RECALIBRATE: 07 01 --> <EMPTY> [OK]
SENSE INTERRUPT: 08 --> 21 00 [OK]
Another example is when the FDC has just been reset. In this
case, you will see up to 4 disk change errors. Again these
are not a real problem and to be expected.
When tracing is turned off, the application tries to be
intelligent about error reporting. The specific errors from
sense interrupt documented above will be suppressed because
they are not a real problem. All other errors will be
displayed.
Error Handling
--------------
There is no automated error retry logic. This is very
intentional since the point is to expose the controller and
drive activity. Any error detected will result in a prompt to
abort, retry, or continue. Note that some number of errors is
considered normal for this technology. An occasional error
would not necessarily be considered a problem.
CPU Speed
---------
Starting with v5.0, the application adjusts it's timing loops
to the actual system CPU speed by querying the BIOS for the
current CPU speed.
Interleave
----------
The format command now allows the specification of a sector
interleave. It is almost always the case that the optimal
interleave will be 2 (meaning 2:1).
360K Media
----------
The 360K media definition should work well for true 360K
drives. However, it will generally not work with 1.2M
drives. This is because these drives spin at 360RPM instead
of the 300RPM speed of true 360K drives. Additionally, 1.2M
drives are 80 tracks and 360K drives are 40 tracks and, so
far, there is no mechanism in FD to "double step" as a way to
use 40 track media in 80 track drives.
With this said, it is possible to configure some 1.2M 5.25"
drives to automatically spin down to 300RPM based on a density
select signal (DENSEL). This signal is asserted by FD for
360K media, so IF you have configured your drive to react to
this signal correctly, you will be able to use the 360K media
defintion. Most 1.2M 5.25" drives are NOT configured this way
by default. TEAC drives are generally easy to modify and have
been tested by the author and do work in this manner. Note
that this does not address the issue of double stepping above;
you will just be using the first 40 of 80 tracks.
Support
-------
I am happy to answer questions as fast and well as I am able.
Best contact is wwarthen@gmail.com or post something on the
RetroBrew Computers Forum
https://www.retrobrewcomputers.org/forum/.
Changes
-------
WW 8/12/2011
Removed call to pulse TC in the FDC initialization after
determining that it periodically caused the FDC to write bad
sectors. I am mystified by this, but definitely found it to
be true. Will revisit at some point -- probably a timing
issue between puslsing TC and whatever happens next.
Non-DMA mode was being set incorrectly for FAST-DMA mode. It
was set for non-DMA even though we were doing DMA. It is
interesting that it worked fine anyway. Fixed it anyway.
DIO_SETMEDIA was not clearing DCD_DSKRDY as it should. Fixed.
WW 8/26/2011: v1.1
Added support for Zeta. Note that INT/WAIT and DRQ/WAIT are
not available on Zeta. Note that Zeta provides the ability to
perform a reset of the FDC independent of a full CPU reset.
This is VERY useful and the FDC is reset anytime a drive reset
is required.
Added INT/WAIT support.
WW 8/28/2011: V1.2
All changes in this version are Zeta specific. Fixed FDC
reset logic and motor status display for Zeta (code from
Sergey).
Modified Zeta disk change display to include it in the command
output line. This makes more sense because a command must be
issued to select the desired drive first. You can use the
SENSE INT command id you want to check the disk change value
at any time. It will also be displayed with any other command
output display.
WW 9/1/2011: V1.3
Added CPUFREQ configuration setting to tune delays based on
cpu speed. The build app is set for 8MHz which also seems to
work well for 4MHz CPU's. Faster CPU speeds will probably
require tuning this setting.
WW 9/5/2011: V1.4
Changed the polling execution routines to utilize CPUFREQ
variable to optimize timeout counter. Most importantly, this
should allow the use of faster CPUs (like 20MHz).
WW 9/19/2011: V1.5
Zeta changes only. Added a call to FDC RESET after any
command failure. This solves an issue where the drive remains
selected if a command error occurs. Also added FDC RESET to
FDC CONTROL menu.
WW 10/7/2011: V2.0
Added support for DIDE. Only supports polling IO and it does
not appear any other modes are possible given the hardware
constraints.
WW 10/13/2011: V2.1
Modified to support N8. N8 is essentially identical to Dual
IDE. The only real change is the IO addresses. In theory, I
should be able to support true DMA on N8 and will work on that.
WW 10/20/2011: v2.2
I had some problems with the results being read were sometimes
missing a byte. Fixed this by taking a more strict approach
to watching the MSR for the exact bits that are expected.
WW 10/22/2011: V2.3
After spending a few days trying to track down an intermittent
data corruption issue with my Dual IDE board, I added a verify
function. This helped me isolate the problem very nicely
(turned out to be interference from the bus monitor).
WW 11/25/2011: V2.4
Preliminary support for DISKIO V3. Basically just assumed
that it operates just like the Zeta. Needs to be verified
with real hardware as soon as I can.
WW 1/9/2012: V2.5
Modified program termination to use CP/M reset call so that a
warm start is done and all drives are logged out. This is
important because media may have been formatted during the
program execution.
WW 2/6/2012: v2.6
Added support for 5.25" drives as tested by Sergio.
WW 4/5/2012: v2.7
Added support for 8" drives as tested by Jim Harre.
WW 4/6/2012: v2.7a
Fixed issue with media selection menu to remove duplicate
entries.
WW 4/8/2012: v2.7b
Corrected the handling of the density select signal.
WW 5/22/2012: v2.8
Added new media definitions (5.25", 320K).
WW 6/1/2012: v2.9
Added interleave capability on format.
WW 6/5/2012: v3.0
Documentation cleanup.
WW 7/1/2012: v3.1
Modified head load time (HLT) for 8" media based on YD-180
spec. Now set to 50ms.
WW 6/17/2013: v3.2
Cleaned up SRT, HLT, and HUT values.
SK 2/10/2015: v3.3
Added Zeta SBC v2 support (Sergey Kiselev)
WW 3/25/2015: v4.0
Renamed from FDTST --> FD
WW 9/2/2017: v5.0
Renamed from FD to FDU.
Added runtime selection of FDC hardware.
Added runtime timing adjustment.
WW 12/16/2017: v5.1
Improved polling version of read/write to fix occasional overrun errors.
WW 1/8/2018: v5.2
Added support for RCBus hardware:
- Scott Baker SMC 9266 FDC module
- Scott Baker WDC 37C65 FDC module
WW 9/5/2018: v5.3
- Removed use of pulsing TC to end R/W operations after one sector and
instead set EOT = R (sector number) so that after desired sector is
read, R/W stops with end of cylinder error which is a documented
method for controling number of sectors R/W. This specific termination
condition is no longer considered an error, but a successful end of
operation.
- Added support for SmallZ80
WW 1/5/2020: v5.4
- Added support for Dyno (based on work by Steve Garcia)
WW 4/29/2020: v5.5
- Added support for Etched Pixels FDC
WW 12/12/2020: v5.6
- Updated SmallZ80 support for new I/O map
WW 3/24/2021: v5.7
- Added support for a few single-sided formats
WW 7/26/2021: v5.8
- Added support for MBC FDC

11
Source/Apps/Makefile

@ -1,14 +1,9 @@
OBJECTS = SysGen.com Survey.com \
SysCopy.com Assign.com Format.com Talk.com Mode.com RTC.com \
Timer.com IntTest.com
OTHERS = *.hex *.com
SUBDIRS = XM FDU FAT Tune
OBJECTS = sysgen.com syscopy.com assign.com format.com talk.com \
mode.com rtc.com timer.com rtchb.com
SUBDIRS = XM FDU FAT Tune Test ZMP ZMD Dev VGM cpuspd Survey
DEST = ../../Binary/Apps DEST = ../../Binary/Apps
TOOLS =../../Tools TOOLS =../../Tools
include $(TOOLS)/Makefile.inc include $(TOOLS)/Makefile.inc
USETASM = 1 USETASM = 1
Survey.com: USETASM=0

1040
Source/Apps/Mode.asm

File diff suppressed because it is too large

1732
Source/Apps/RTC.asm

File diff suppressed because it is too large

725
Source/Apps/Survey.asm

@ -1,725 +0,0 @@
;***************************************;
; ;
; S U R V E Y ;
; ;
;***************************************;
;By Michael Friese 9/22/79
;* Lists Kbytes used and remaining plus number of files
; on all logged disks (up to 8)
;* Prints Memory map and synopsis of all machine memory
;* Lists all active I/O Ports
;* Uses disk allocation block for all disk calculations
;
;VERSION LIST - Most recent version first.
;
;16/Dec/17 - Handle 16-bit port addressing using
; Z80 IN A,(C) instruction. Wayne Warthen
;
;06/Jul/82 - Added Godbout DISK 1 equate and added SKIP equate
; Bill Bolton - Software Tools, Australia
;
;01/Jun/82 - Tidied up and fixed port display, added display
; of contents of low memory. David Bennett - Alfred
; Hospital, Australia
;
;29/Jun/80 - Added version number test and calculations for CP/M
; version 2 compatibility. This program should now work
; properly on all versions 1.4 and later. BRR
;
;28/Jun/80 - Added IMS400 equate (prevents Industrial Micro Systems
; controller from hanging up during port scan). BRR
;
;24/Jun/80 - Removed MACLIB statement, included required macros
; in source. Bruce R. Ratoff
;
;*******************************;
; SYSTEM MACROS ;
;*******************************;
;Increments 16 bit memory location X
INXI MACRO X
LOCAL JUST8
PUSH H
LXI H,X
INR M
JNZ JUST8
INX H
INR M
JUST8:
POP H
ENDM
;..............................................................
;
; SAVE MACRO SAVE SPECIFIED REGISTERS
;
; SAVE R1,R2,R3,R4
;
; R1-R4 MAY BE B,D,H OR PSW SAVED IN ORDER SPECIFIED
; IF REGS ARE OMITTED SAVE B,D AND H
;
SAVE MACRO R1,R2,R3,R4
IF NOT NUL R1&R2&R3&R4
IRP R,<<R1>,<R2>,<R3>,<R4>>
IF NUL R
EXITM
ENDIF
PUSH R
ENDM
ELSE
IRPC REG,BDH
PUSH REG
ENDM
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; RESTORE MACRO RESTORE REGISTERS (INVERSE OF SAVE)
;
; RESTORE R1,R2,R3,R4
;
; R1-R4 MAY BE B,D,H OR PSW RESTORED IN ORDER SPECIFIED
; IF REGS OMITTED RESTORE H,D AND B
;
RESTORE MACRO R1,R2,R3,R4
IF NOT NUL R1&R2&R3&R4
IRP R,<<R1>,<R2>,<R3>,<R4>>
IF NUL R
EXITM
ENDIF
POP R
ENDM
ELSE
IRPC REG,HDB
POP REG
ENDM
ENDIF
ENDM
;
;..............................................................
;
; CHAROUT MACRO CONSOLE OUTPUT FROM A
;
; CHAROUT ADDR
;
CHAROUT MACRO ADDR
IF NOT NUL ADDR
LDA ADDR
ENDIF
MVI C,2 ;;CONOUT
MOV E,A ;;CHAR TO E
CALL 5 ;;CALL BDOS
ENDM
;
;
;.............................................................
;
; DECOUT MACRO CONVERT A POSITIVE INTEGER TO DECIMAL AND OUTPUT
; TO THE CONSOLE.
;
; DECOUT ADDR
;
; IF ADDR OMITTED, NUMBER ASSUMED TO BE IN HL, ELSE LOADED TO HL
; LEADING ZEROS SUPRESSED. MAXIMUM NUMBER 65,767
;
DECOUT MACRO ADDR
LOCAL ENDDEC,DX
JMP ENDDEC
@DECOUT:
SAVE ;;PUSH STACK
LXI B,-10 ;;RADIX FOR CONVERSION
LXI D,-1 ;;THIS BECOMES NO DIVIDED BY RADIX
DX:
DAD B ;;SUBTRACT 10
INX D
JC DX
LXI B,10
DAD B ;;ADD RADIX BACK IN ONCE
XCHG
MOV A,H
ORA L ;;TEST FOR ZERO
CNZ @DECOUT ;;RECURSIVE CALL
MOV A,E
ADI '0' ;;CONVERT FROM BCD TO HEX
MOV E,A ;;TO E FOR OUTPUT
CHAROUT ;;CONSOLE OUTPUT
RESTORE ;;POP STACK
RET
ENDDEC:
DECOUT MACRO ?ADDR
IF NOT NUL ?ADDR
LHLD ?ADDR
ENDIF
CALL @DECOUT ;;CALL THE SUBROUTINE
ENDM
DECOUT ADDR
ENDM
;
;
;..............................................................
;
; HEXOUT MACRO CONVERT BINARY NO AND OUTPUT TO CONSOLE
;
; HEXOUT ADDR
;
; NUMBER ASSUMED IN A IF NO ARGUMENT
;
HEXOUT MACRO ADDR
LOCAL OUTCHR,HEXEND
JMP HEXEND
HEXPRN:
SAVE PSW
RRC
RRC
RRC
RRC ;;SHIFT RIGHT 4
CALL OUTCHR
RESTORE PSW
OUTCHR:
ANI 0FH ;;MASK 4 BITS
ADI 90H ;;ADD OFFSET
DAA ;;DEC ADJUST
ACI 40H ;;ADD OFFSET
DAA ;;DEC ADJUST
MOV E,A ;;TO E FOR OUTPUT
MVI C,2 ;;CONOUT
JMP 5 ;;CALL BDOS
HEXEND:
HEXOUT MACRO ?ADDR
IF NOT NUL ?ADDR
LDA ?ADDR
ENDIF
CALL HEXPRN
ENDM
HEXOUT ADDR
ENDM
;
;
;*******************************;
; SYSTEM EQUATES ;
;*******************************;
TRUE EQU -1
FALSE EQU NOT TRUE
TARBEL EQU FALSE ; Tarbell FDC dmb 31-may-82
IMS400 EQU FALSE ; Industrial Micro Systems FDC
GODBOUT EQU FALSE ; Godbout Disk 1 FDC
GODBAS EQU 0C0H ; Base of Godbout FDC
TARBAS EQU 0F8H ; Base of Tarbell
SKIP EQU TARBEL OR IMS400 OR GODBOUT ; Will be true
; if any skip needed
IF TARBEL
SKIPORT EQU TARBAS+4 ; Port # to skip if Tarbell FDC
ENDIF
IF IMS400
SKIPORT EQU 08FH ; Port # to skip if IMS FDC
ENDIF
IF GODBOUT
SKIPORT EQU GODBAS+1 ; Port # to skip if Disk 1 FDC
ENDIF
BDOS EQU 5 ; jump to BDOS
bios equ 0 ; jump to BIOS dmb 1-jun-82
CRLF EQU 0A0DH ; CR LF sequence
CRLFE EQU 8A0DH ; CR LF with EOL
EOL EQU 80H ; End of line
TAB EQU 'I'-40H ; Tab character
ESC EQU 1BH ; Escape character
TABS EQU 9 ; Tab columns
;***********************;
; MAIN PROGRAM ;
;***********************;
;
ORG 100H
;
START:
LXI H,0 ; Save stack pointer
DAD SP
SHLD OLDSP
LXI SP,FINIS+64
CALL TYPE ; Type initial CRLF
DB TAB,TAB,'*** System Survey (December 17) ***'
DW CRLF,CRLFE
;DISK SURVEY
LXI H,8 ; Init drive counter
MVI C,24 ; Get login vector
PUSH H
CALL BDOS
POP H
ROTBIT:
RAR ; RAR login bit to C
JNC NOTLOG ; Drive not logged
PUSH PSW ; Save login
PUSH H ; and counter
;Print drive letter
CALL TYPE
DB 'Drive'
DB ' '+EOL
MVI A,'A' ; Get ASCII bias
ADD H ; Add to drive #
MOV E,A ; Print drive letter
CALL TCHR
CALL TYPE ; and colon
DB ':',' '+EOL
POP H ; Restore drive #
PUSH H
;Print K already allocated
MOV E,H
MVI C,14 ; Log drive
CALL BDOS
MVI C,27 ; Index allocation vect
CALL BDOS
MOV L,A ; Put in decent regs
MOV H,B
PUSH H ; save for later
MVI C,12 ; get version #
CALL BDOS
MOV A,L ; zero if version 1
ORA A
JNZ V2X ; otherwise, use 2.x style params
LHLD BDOS+1 ; get vers 1 style params
MVI L,3CH
MOV A,M ; get block shift factor
STA BLKSHF
INX H
INX H
MOV L,M ; get max. block number
MVI H,0
SHLD MAXALL
MVI B,32 ; assume 32 bytes in block map
JMP GETALC ; continue
V2X:
MVI A,'?' ; Use wild user #
STA FCB ; in filename search
MVI C,31 ; Get 2.x parameter block
CALL BDOS
INX H
INX H
MOV A,M ; Get and save ablock shift factor
STA BLKSHF
INX H
INX H
INX H
MOV A,M ; Get maximum block number
INX H ; (double precision)
MOV H,M
MOV L,A
SHLD MAXALL
INX H
MVI B,3 ; map size is (MAXALL+1)/8
V2SH:
MOV A,H
ORA A ; do 16 bit right shift
RAR
MOV H,A
MOV A,L
RAR
MOV L,A
DCR B ; 3 times
JNZ V2SH
MOV B,L
LDA MAXALL ; allow for leftover bits if any
ANI 3
JZ GETALC
INR B
GETALC:
POP H
LXI D,0 ; Init group counter
NXBYTE:
MVI C,8 ; Bit counter for byte
MOV A,M ; Get map byte
NXBIT:
RAR ; Rotate to C
JNC NOBIT ; No group allocated
INX D ; Inc group counter
NOBIT:
DCR C ; Dec bit counter
JNZ NXBIT
INX H ; Index next byte
DCR B
JNZ NXBYTE
CALL SHF16
PUSH H
CALL BINDEC
CALL TYPE
DB 'K bytes in',' '+EOL
;Print number of files
LXI D,FCB ; Fake file cont block
MVI C,17 ; Search for 1st file
CALL BDOS
LXI H,0 ; File counter
LOOK:
CPI 255 ; Failure
JZ PFILE
ADD A ; File offset times 2
ADD A ; 4
ADD A ; 8
ADD A ; 16
ADD A ; 32
ADI 80H ; Make sure it's not a deleted file
MOV E,A
MVI D,0
LDAX D
CPI 0E5H
JZ LOOK1
INX H ; Bump file counter
LOOK1:
LXI D,FCB ; Restore FCB
MVI C,18 ; Look for addtl files
PUSH H ; Save file counter
CALL BDOS
POP H
JMP LOOK
PFILE:
CALL BINDEC ; Print # of files
CALL TYPE
DB ' files with',' '+EOL
;Print K remaining
LHLD MAXALL ; Get number of blocks
XCHG
INX D ; Inc for actual value
CALL SHF16
XCHG
POP H
MOV A,H ; Ones comp & move
CMA
MOV H,A
MOV A,L
CMA
MOV L,A
INX H ; Twos complement
DAD D ; and subtract
CALL BINDEC ; K remaining
CALL TYPE
DB 'K bytes remaining'
DW CRLFE
;Set up to print next drive
POP H ; Restore bit counter
POP PSW ; and bitmap byte
NOTLOG:
INR H ; Bump drive counter
DCR L ; Dec bit counter
JNZ ROTBIT
;MEMORY SURVEY
;Create header
MSURV:
CALL TYPE
DW CRLF
DB 'Memory map:'
DW CRLF
DB '0',TAB,'8',TAB,'16',TAB,'24',TAB,'32'
DB TAB,'40',TAB,'48',TAB,'56',TAB,'64'
DW CRLF
REPT 8
DB '|',TAB
ENDM
DB '|'
DW CRLF
db ' ' ; dmb 31-May-82
DB 'T'+EOL
LXI H,RAM
MVI M,LOW 1023 ; Init RAM counter
INX H
MVI M,HIGH 1023
MVI B,4 ; Clear ROM, EMP
CLREG:
INX H
MVI M,0
DCR B
JNZ CLREG
LXI H,1024 ; Init memory pointer
MVI C,63 ; K to be checked
;Start of analysis loop
BEGANA:
LXI D,1024 ; Byte counter
XRA A ; Clear flag bytes
STA RAMF
STA EMPF
ANALP:
MOV A,M ; Get test byte and
MOV B,A ; store for later
CMA
MOV M,A ; Put invertd tst byte
SUB M ; Check for good write
MOV M,B ; Restore orignl data
JNZ NOTMEM ; Wasn't good write
INXI RAM ; Bump memory counter
JMP NEXT ; To next byte
NOTMEM:
STA RAMF ; Not considered RAM
MVI A,0FFH ; Is it empty space?
SUB B
JNZ NOTEMP ; Inc ROM, set flag
LDA EMPF ; Any non empty space
ANA A ; before here?
JZ NEXT
JMP NOTEM ; To next byte
NOTEMP:
STA EMPF ; Set no empty flag
NOTEM:
INXI ROM
NEXT:
INX H ; Index next byte
DCX D ; Decrement K counter
XRA A
ORA D
ORA E
JNZ ANALP ; K counter not 0
PUSH B
PUSH H
LDA RAMF ; Is it RAM?
ANA A
JNZ NOTRAM ; No
dcr h ; drop H to make compares right
LDA BDOS+2 ; Is it under BDOS ?
CMP H
JC NOTTPA ; No
CALL TYPE ; Yes, it's TPA
DB 'T'+EOL
JMP NEXTK
NOTTPA:
lda bios+2 ; is it under bios ?
cmp h
jc nbdos
call type ; yes, it's BDOS
db 'C'+eol
jmp nextk
nbdos:
CALL TYPE ; Assume it's BIOS
DB 'B'+EOL
JMP NEXTK
;
NOTRAM:
LDA EMPF ; Is it empty?
ANA A
JZ NOMEM ; Yes, no memory
CALL TYPE ; No, must be ROM
DB 'R'+EOL
JMP NEXTK
NOMEM:
CALL TYPE
DB ' '+EOL
NEXTK:
POP H
POP B
DCR C ; Decrement K counter
JNZ BEGANA
CALL TYPE
DW CRLF
DB 'T=TPA',TAB,'C=CPM',TAB,'B=BIOS or unassigned'
DB TAB,'R=ROM or bad'
DW CRLFE
;
; contents of first page
call type
db 'BIOS at',' '+eol
hexout bios+2
hexout bios+1
call type
db tab,'iobyte',' '+eol
hexout bios+3
call type
db tab,'drive',' '+eol
hexout bios+4
call type
db tab,'BDOS at',' '+eol
hexout bdos+2
hexout bdos+1
call type
dw crlf,crlfe
;
;MEMORY SYNOPSIS
LHLD RAM
PUSH H ; Save RAM
CALL BINDEC ; Type RAM
CALL TYPE
DB ' Bytes RAM',TAB,TAB+EOL
LHLD ROM
PUSH H
CALL BINDEC ; Type ROM
CALL TYPE
DB ' Bytes ROM',TAB,TAB+EOL
LHLD BDOS+1
CALL BINDEC
CALL TYPE
DB ' Bytes in TPA'
DW CRLFE
POP D ; Get RAM
POP H ; Get RAM
DAD D ; Add 'em
PUSH H ; and save result
LXI D,0 ; Subtract from this
MOV A,H ; Complement 16 bits
CMA
MOV H,A
MOV A,L
CMA
MOV L,A ; 2s comp bias in D
DAD D ; Subtract
CALL BINDEC
CALL TYPE
DB ' Bytes Empty ',TAB+EOL
POP H ; Restore RAM+ROM
CALL BINDEC
CALL TYPE
DB ' Total Active Bytes'
DW CRLF,CRLF
;PORT SURVEY
DB 'Active I/O ports',':'+EOL
LXI H,1000H ; DELAY SO MESSAGE OUTPUT
PDLY:
DCX H ; DOESN'T GIVE A FALSE READING
MOV A,H ; ON CONSOLE STATUS PORT
ORA L
JNZ PDLY
LXI H,0 ; Init active port counter
mvi d,0 ; Init port counter
mvi e,0ffh ; init port group variable
PORTLP:
MOV A,D
IF SKIP ; Single port mask
CPI SKIPORT
JZ ISPORT ; Print mask port
ENDIF
mov c,a ; port number to reg c
mvi b,0 ; for 16 bit port addressing
db 0edh,078h ; z80: in a,(c)
; inactive port could return 0xFF or 0x78
CPI 0FFH
JZ NEXTPT
cpi 078h
jz nextpt
ISPORT:
mov a,d ; got a live one, probably
ani 0f0h ; is port in same group as last ?
cmp e
jz nocrlf
call type ; no, start a new line
dw crlfe
mov a,d ; save for next time
ani 0f0h
mov e,a
nocrlf:
MOV A,D ; Get port #
PUSH D
PUSH H
HEXOUT
POP H
POP D
INX H ; count another one found
call type
db ' '+eol
NEXTPT:
INR D ; Bump port counter
JNZ PORTLP ; Not done
CALL TYPE ; Done
DW CRLFE
CALL BINDEC
CALL TYPE ; Type Active Ports
DB ' Ports active'
DW CRLFE
CCP:
LHLD OLDSP
SPHL
RET
;***********************;
; SUBROUTINES ;
;***********************;
;Binary to decimal conversion
BINDEC:
DECOUT ; From LIB
RET
;Types a string of text terminated with bit 7 high
TYPE:
XTHL ; Get string address
PUSH D
TYPELP:
MOV A,M ; Get type data
MOV D,A ; Save for later
ANI 7FH ; Mask ASCII
MOV E,A
PUSH H
PUSH D
CALL TCHR
POP D
POP H
INX H
MVI A,EOL ; End of line bit
ANA D
JP TYPELP ; Not done
POP D
XTHL ; Get return address
RET
;Types a single character on console
TCHR:
MVI C,2
JMP BDOS
;Checks sectors per block and multiplies or divides block size
;Enter with data in D. Result returned in H,L
;
SHF16:
LDA BLKSHF ; Get shift factor (gives block size)
CPI 3 ; Is it 1K (std)?
JNZ NOT3
MOV L,E ; Yes, use present #
ZH:
MVI H,0
RET
;
NOT3:
CPI 2 ; Is it minifloppy?
JNZ NOT2
MOV A,E ; Yes, divide by 2
RRC
ANI 7FH
MOV L,A
JMP ZH
NOT2:
SUI 3 ; Must be something
MOV B,A ; larger like double
XCHG ; sided or double dens
BITSHF:
DAD H ; 16 bit 2^(B-1)
DCR B
JNZ BITSHF
RET
;***********************;
; DATA STORAGE ;
;***********************;
FCB: DB 0,'???????????',0,0,0 ; File control block
DS 17 ; Extra FCB workspace
OLDSP: DS 2 ; Old stack pointer
RAM: DS 2 ; RAM counter
ROM: DS 2 ; ROM counter
RAMF: DS 1 ; RAM good flag
EMPF: DS 1 ; Empty so far flag
BLKSHF: DS 1 ; block shift factor
MAXALL: DS 2 ; maximum block number
FINIS EQU $ ; End of program
END


16
Source/Apps/Survey/Build.cmd

@ -0,0 +1,16 @@
@echo off
setlocal
set TOOLS=..\..\..\Tools
set PATH=%TOOLS%\zxcc;%PATH%
set CPMDIR80=%TOOLS%/cpm/
:: zxcc MAC survey.asm -$PO || exit /b
:: zxcc MLOAD25 survey || exit /b
zxcc M80 -,=survey/L/R
zxcc L80 -survey,survey/N/E
copy /Y survey.com ..\..\..\Binary\Apps\ || exit /b

8
Source/Apps/Survey/Clean.cmd

@ -0,0 +1,8 @@
@echo off
setlocal
if exist *.hex del *.hex
if exist *.rel del *.rel
if exist *.prn del *.prn
if exist *.lst del *.lst
if exist *.com del *.com

6
Source/Apps/Survey/Makefile

@ -0,0 +1,6 @@
OBJECTS = survey.com
DEST = ../../../Binary/Apps
TOOLS = ../../../Tools
OTHERS = *.hex
include $(TOOLS)/Makefile.inc

830
Source/Apps/Survey/survey.mac

@ -0,0 +1,830 @@
;***************************************;
; ;
; S U R V E Y ;
; ;
;***************************************;
;By Michael Friese 9/22/79
;* Lists Kbytes used and remaining plus number of files
; on all logged disks (up to 8)
;* Prints Memory map and synopsis of all machine memory
;* Lists all active I/O Ports
;* Uses disk allocation block for all disk calculations
;
;VERSION LIST - Most recent version first.
;
;10/Feb/23 - Total hack to avoid crash on ECB SBC
; RomWBW now required by this version
; Wayne Warthen
;
;16/Dec/17 - Handle 16-bit port addressing using
; Z80 IN A,(C) instruction. Wayne Warthen
;
;06/Jul/82 - Added Godbout DISK 1 equate and added SKIP equate
; Bill Bolton - Software Tools, Australia
;
;01/Jun/82 - Tidied up and fixed port display, added display
; of contents of low memory. David Bennett - Alfred
; Hospital, Australia
;
;29/Jun/80 - Added version number test and calculations for CP/M
; version 2 compatibility. This program should now work
; properly on all versions 1.4 and later. BRR
;
;28/Jun/80 - Added IMS400 equate (prevents Industrial Micro Systems
; controller from hanging up during port scan). BRR
;
;24/Jun/80 - Removed MACLIB statement, included required macros
; in source. Bruce R. Ratoff
;
;*******************************;
; SYSTEM MACROS ;
;*******************************;
;Increments 16 bit memory location X
INXI MACRO X
LOCAL JUST8
PUSH H
LXI H,X
INR M
JNZ JUST8
INX H
INR M
JUST8:
POP H
ENDM
;..............................................................
;
; SAVE MACRO SAVE SPECIFIED REGISTERS
;
; SAVE R1,R2,R3,R4
;
; R1-R4 MAY BE B,D,H OR PSW SAVED IN ORDER SPECIFIED
; IF REGS ARE OMITTED SAVE B,D AND H
;
SAVE MACRO R1,R2,R3,R4
IF NOT NUL R1&R2&R3&R4
IRP R,<<R1>,<R2>,<R3>,<R4>>
IF NUL R
EXITM
ENDIF
PUSH R
ENDM
ELSE
IRPC REG,BDH
PUSH REG
ENDM
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; RESTORE MACRO RESTORE REGISTERS (INVERSE OF SAVE)
;
; RESTORE R1,R2,R3,R4
;
; R1-R4 MAY BE B,D,H OR PSW RESTORED IN ORDER SPECIFIED
; IF REGS OMITTED RESTORE H,D AND B
;
RESTORE MACRO R1,R2,R3,R4
IF NOT NUL R1&R2&R3&R4
IRP R,<<R1>,<R2>,<R3>,<R4>>
IF NUL R
EXITM
ENDIF
POP R
ENDM
ELSE
IRPC REG,HDB
POP REG
ENDM
ENDIF
ENDM
;
;..............................................................
;
; CHAROUT MACRO CONSOLE OUTPUT FROM A
;
; CHAROUT ADDR
;
CHAROUT MACRO ADDR
IF NOT NUL ADDR
LDA ADDR
ENDIF
MVI C,2 ;;CONOUT
MOV E,A ;;CHAR TO E
CALL 5 ;;CALL BDOS
ENDM
;
;
;.............................................................
;
; DECOUT MACRO CONVERT A POSITIVE INTEGER TO DECIMAL AND OUTPUT
; TO THE CONSOLE.
;
; DECOUT ADDR
;
; IF ADDR OMITTED, NUMBER ASSUMED TO BE IN HL, ELSE LOADED TO HL
; LEADING ZEROS SUPRESSED. MAXIMUM NUMBER 65,767
;
DECOUT MACRO ADDR
LOCAL ENDDEC,DX
JMP ENDDEC
@DECOUT:
SAVE ;;PUSH STACK
LXI B,-10 ;;RADIX FOR CONVERSION
LXI D,-1 ;;THIS BECOMES NO DIVIDED BY RADIX
DX:
DAD B ;;SUBTRACT 10
INX D
JC DX
LXI B,10
DAD B ;;ADD RADIX BACK IN ONCE
XCHG
MOV A,H
ORA L ;;TEST FOR ZERO
CNZ @DECOUT ;;RECURSIVE CALL
MOV A,E
ADI '0' ;;CONVERT FROM BCD TO HEX
MOV E,A ;;TO E FOR OUTPUT
CHAROUT ;;CONSOLE OUTPUT
RESTORE ;;POP STACK
RET
ENDDEC:
DECOUT MACRO ?ADDR
IF NOT NUL ?ADDR
LHLD ?ADDR
ENDIF
CALL @DECOUT ;;CALL THE SUBROUTINE
ENDM
DECOUT ADDR
ENDM
;
;
;..............................................................
;
; HEXOUT MACRO CONVERT BINARY NO AND OUTPUT TO CONSOLE
;
; HEXOUT ADDR
;
; NUMBER ASSUMED IN A IF NO ARGUMENT
;
HEXOUT MACRO ADDR
LOCAL OUTCHR,HEXEND
JMP HEXEND
HEXPRN:
SAVE PSW
RRC
RRC
RRC
RRC ;;SHIFT RIGHT 4
CALL OUTCHR
RESTORE PSW
OUTCHR:
ANI 0FH ;;MASK 4 BITS
ADI 90H ;;ADD OFFSET
DAA ;;DEC ADJUST
ACI 40H ;;ADD OFFSET
DAA ;;DEC ADJUST
MOV E,A ;;TO E FOR OUTPUT
MVI C,2 ;;CONOUT
JMP 5 ;;CALL BDOS
HEXEND:
HEXOUT MACRO ?ADDR
IF NOT NUL ?ADDR
LDA ?ADDR
ENDIF
CALL HEXPRN
ENDM
HEXOUT ADDR
ENDM
;
;
;*******************************;
; SYSTEM EQUATES ;
;*******************************;
TRUE EQU -1
FALSE EQU NOT TRUE
TARBEL EQU FALSE ; Tarbell FDC dmb 31-may-82
IMS400 EQU FALSE ; Industrial Micro Systems FDC
GODBOUT EQU FALSE ; Godbout Disk 1 FDC
GODBAS EQU 0C0H ; Base of Godbout FDC
TARBAS EQU 0F8H ; Base of Tarbell
SKIP EQU TARBEL OR IMS400 OR GODBOUT ; Will be true
; if any skip needed
IF TARBEL
SKIPORT EQU TARBAS+4 ; Port # to skip if Tarbell FDC
ENDIF
IF IMS400
SKIPORT EQU 08FH ; Port # to skip if IMS FDC
ENDIF
IF GODBOUT
SKIPORT EQU GODBAS+1 ; Port # to skip if Disk 1 FDC
ENDIF
BDOS EQU 5 ; jump to BDOS
bios equ 0 ; jump to BIOS dmb 1-jun-82
CRLF EQU 0A0DH ; CR LF sequence
CRLFE EQU 8A0DH ; CR LF with EOL
EOL EQU 80H ; End of line
TAB EQU 'I'-40H ; Tab character
ESC EQU 1BH ; Escape character
TABS EQU 9 ; Tab columns
;***********************;
; MAIN PROGRAM ;
;***********************;
;
;ORG 100H
;
;
;
.Z80
LD HL,IMGORG
LD DE,START
LD BC,IMGEND-IMGORG
LDIR
JP START
.8080
;
IMGORG:
;
.PHASE 8000H
;
START:
LXI H,0 ; Save stack pointer
DAD SP
SHLD OLDSP
LXI SP,FINIS+64
CALL TYPE ; Type initial CRLF
DW CRLF,CRLF
DB TAB,'*** RomWBW System Survey (Feb 2023) ***'
DW CRLF,CRLFE
;DISK SURVEY
LXI H,8 ; Init drive counter
MVI C,24 ; Get login vector
PUSH H
CALL BDOS
POP H
ROTBIT:
RAR ; RAR login bit to C
JNC NOTLOG ; Drive not logged
PUSH PSW ; Save login
PUSH H ; and counter
;Print drive letter
CALL TYPE
DB 'Drive'
DB ' '+EOL
MVI A,'A' ; Get ASCII bias
ADD H ; Add to drive #
MOV E,A ; Print drive letter
CALL TCHR
CALL TYPE ; and colon
DB ':',' '+EOL
POP H ; Restore drive #
PUSH H
;Print K already allocated
MOV E,H
MVI C,14 ; Log drive
CALL BDOS
MVI C,27 ; Index allocation vect
CALL BDOS
MOV L,A ; Put in decent regs
MOV H,B
PUSH H ; save for later
MVI C,12 ; get version #
CALL BDOS
MOV A,L ; zero if version 1
ORA A
JNZ V2X ; otherwise, use 2.x style params
LHLD BDOS+1 ; get vers 1 style params
MVI L,3CH
MOV A,M ; get block shift factor
STA BLKSHF
INX H
INX H
MOV L,M ; get max. block number
MVI H,0
SHLD MAXALL
MVI B,32 ; assume 32 bytes in block map
JMP GETALC ; continue
V2X:
MVI A,'?' ; Use wild user #
STA FCB ; in filename search
MVI C,31 ; Get 2.x parameter block
CALL BDOS
INX H
INX H
MOV A,M ; Get and save ablock shift factor
STA BLKSHF
INX H
INX H
INX H
MOV A,M ; Get maximum block number
INX H ; (double precision)
MOV H,M
MOV L,A
SHLD MAXALL
INX H
MVI B,3 ; map size is (MAXALL+1)/8
V2SH:
MOV A,H
ORA A ; do 16 bit right shift
RAR
MOV H,A
MOV A,L
RAR
MOV L,A
DCR B ; 3 times
JNZ V2SH
MOV B,L
LDA MAXALL ; allow for leftover bits if any
ANI 3
JZ GETALC
INR B
GETALC:
POP H
LXI D,0 ; Init group counter
NXBYTE:
MVI C,8 ; Bit counter for byte
MOV A,M ; Get map byte
NXBIT:
RAR ; Rotate to C
JNC NOBIT ; No group allocated
INX D ; Inc group counter
NOBIT:
DCR C ; Dec bit counter
JNZ NXBIT
INX H ; Index next byte
DCR B
JNZ NXBYTE
CALL SHF16
PUSH H
CALL BINDEC
CALL TYPE
DB 'K bytes in',' '+EOL
;Print number of files
LXI D,FCB ; Fake file cont block
MVI C,17 ; Search for 1st file
CALL BDOS
LXI H,0 ; File counter
LOOK:
CPI 255 ; Failure
JZ PFILE
ADD A ; File offset times 2
ADD A ; 4
ADD A ; 8
ADD A ; 16
ADD A ; 32
ADI 80H ; Make sure it's not a deleted file
MOV E,A
MVI D,0
LDAX D
CPI 0E5H
JZ LOOK1
INX H ; Bump file counter
LOOK1:
LXI D,FCB ; Restore FCB
MVI C,18 ; Look for addtl files
PUSH H ; Save file counter
CALL BDOS
POP H
JMP LOOK
PFILE:
CALL BINDEC ; Print # of files
CALL TYPE
DB ' files with',' '+EOL
;Print K remaining
LHLD MAXALL ; Get number of blocks
XCHG
INX D ; Inc for actual value
CALL SHF16
XCHG
POP H
MOV A,H ; Ones comp & move
CMA
MOV H,A
MOV A,L
CMA
MOV L,A
INX H ; Twos complement
DAD D ; and subtract
CALL BINDEC ; K remaining
CALL TYPE
DB 'K bytes remaining'
DW CRLFE
;Set up to print next drive
POP H ; Restore bit counter
POP PSW ; and bitmap byte
NOTLOG:
INR H ; Bump drive counter
DCR L ; Dec bit counter
JNZ ROTBIT
;MEMORY SURVEY
;Create header
MSURV:
CALL TYPE
DW CRLF
DB 'Memory map:'
DW CRLF
DB '0',TAB,'8',TAB,'16',TAB,'24',TAB,'32'
DB TAB,'40',TAB,'48',TAB,'56',TAB,'64'
DW CRLF
REPT 8
DB '|',TAB
ENDM
DB '|'
DW CRLF
db ' ' ; dmb 31-May-82
DB 'T'+EOL
LXI H,RAM
MVI M,LOW 1023 ; Init RAM counter
INX H
MVI M,HIGH 1023
MVI B,4 ; Clear ROM, EMP
CLREG:
INX H
MVI M,0
DCR B
JNZ CLREG
LXI H,1024 ; Init memory pointer
MVI C,63 ; K to be checked
;Start of analysis loop
BEGANA:
LXI D,1024 ; Byte counter
XRA A ; Clear flag bytes
STA RAMF
STA EMPF
ANALP:
MOV A,M ; Get test byte and
MOV B,A ; store for later
CMA
MOV M,A ; Put invertd tst byte
SUB M ; Check for good write
MOV M,B ; Restore orignl data
JNZ NOTMEM ; Wasn't good write
INXI RAM ; Bump memory counter
JMP NEXT ; To next byte
NOTMEM:
STA RAMF ; Not considered RAM
MVI A,0FFH ; Is it empty space?
SUB B
JNZ NOTEMP ; Inc ROM, set flag
LDA EMPF ; Any non empty space
ANA A ; before here?
JZ NEXT
JMP NOTEM ; To next byte
NOTEMP:
STA EMPF ; Set no empty flag
NOTEM:
INXI ROM
NEXT:
INX H ; Index next byte
DCX D ; Decrement K counter
XRA A
ORA D
ORA E
JNZ ANALP ; K counter not 0
PUSH B
PUSH H
LDA RAMF ; Is it RAM?
ANA A
JNZ NOTRAM ; No
dcr h ; drop H to make compares right
LDA BDOS+2 ; Is it under BDOS ?
CMP H
JC NOTTPA ; No
CALL TYPE ; Yes, it's TPA
DB 'T'+EOL
JMP NEXTK
NOTTPA:
lda bios+2 ; is it under bios ?
cmp h
jc nbdos
call type ; yes, it's BDOS
db 'C'+eol
jmp nextk
nbdos:
CALL TYPE ; Assume it's BIOS
DB 'B'+EOL
JMP NEXTK
;
NOTRAM:
LDA EMPF ; Is it empty?
ANA A
JZ NOMEM ; Yes, no memory
CALL TYPE ; No, must be ROM
DB 'R'+EOL
JMP NEXTK
NOMEM:
CALL TYPE
DB ' '+EOL
NEXTK:
POP H
POP B
DCR C ; Decrement K counter
JNZ BEGANA
CALL TYPE
DW CRLF
DB 'T=TPA',TAB,'C=CPM',TAB,'B=BIOS or unassigned'
DB TAB,'R=ROM or bad'
DW CRLFE
;
; contents of first page
call type
db 'BIOS at',' '+eol
hexout bios+2
hexout bios+1
call type
db tab,'iobyte',' '+eol
hexout bios+3
call type
db tab,'drive',' '+eol
hexout bios+4
call type
db tab,'BDOS at',' '+eol
hexout bdos+2
hexout bdos+1
call type
dw crlf,crlfe
;
;MEMORY SYNOPSIS
LHLD RAM
PUSH H ; Save RAM
CALL BINDEC ; Type RAM
CALL TYPE
DB ' Bytes RAM',TAB,TAB+EOL
LHLD ROM
PUSH H
CALL BINDEC ; Type ROM
CALL TYPE
DB ' Bytes ROM',TAB,TAB+EOL
LHLD BDOS+1
CALL BINDEC
CALL TYPE
DB ' Bytes in TPA'
DW CRLFE
POP D ; Get RAM
POP H ; Get RAM
DAD D ; Add 'em
PUSH H ; and save result
LXI D,0 ; Subtract from this
MOV A,H ; Complement 16 bits
CMA
MOV H,A
MOV A,L
CMA
MOV L,A ; 2s comp bias in D
DAD D ; Subtract
CALL BINDEC
CALL TYPE
DB ' Bytes Empty ',TAB+EOL
POP H ; Restore RAM+ROM
CALL BINDEC
CALL TYPE
DB ' Total Active Bytes'
DW CRLF,CRLF
;PORT SURVEY
DB 'Active I/O ports',':'+EOL
LXI H,1000H ; DELAY SO MESSAGE OUTPUT
PDLY:
DCX H ; DOESN'T GIVE A FALSE READING
MOV A,H ; ON CONSOLE STATUS PORT
ORA L
JNZ PDLY
;
.Z80
; record the active bank
ld a,(0ffe0h) ; get current hbios bank id
ld (BANK),a ; and save it
; Check for Z180 CPU
xor a ; assume Z80
ld (IS180),a ; save it
ld de,0506H ; 5 x 6
db 0EDH,05CH ; MLT DE: de = 30 if z180
ld a,e ; result to A
cp 30 ; check if multiply happened
jr nz,z80 ; if invalid, then Z80
or 0ffH ; flag value for Z180
ld (IS180),a ; save it
z80:
.8080
;
LXI H,0 ; Init active port counter
mvi d,0 ; Init port counter
mvi e,0ffh ; init port group variable
PORTLP:
MOV A,D
IF SKIP ; Single port mask
CPI SKIPORT
JZ ISPORT ; Print mask port
ENDIF
;
.Z80
di ; interrupts off
ld a,(IS180) ; Z180?
or a
jr nz,rd180
;
; Z80 port read
; Read port using IN A,(C), push result
ld a,d
ld c,a
ld (pnum0a),a ; dynamic update
ld (pnum0b),a ; dynamic update
ld b,0
in a,(c)
push af
; Read port using IN A,(port), push result
in a,(0ffh) ; IN0
pnum0a equ $-1
push af
; Read port using IN A,(port), push result
in a,(0ffh) ; IN0
pnum0b equ $-1
push af
jr rdz
;
rd180:
; Z180 port read
; Read port using IN A,(C), push result
ld a,d
ld c,a
ld (pnum1a),a ; dynamic update
ld (pnum1b),a ; dynamic update
ld b,0
in a,(c)
push af
; Read port using IN0 A,(port), push result
db 0EDH,038H,0FFH ; IN0
pnum1a equ $-1
push af
; Read port using IN0 A,(port), push result
db 0EDH,038H,0FFH ; IN0
pnum1b equ $-1
push af
;
rdz:
; Make sure correct bank is still selected!
push af
ld a,(BANK)
call 0FFF3H
pop af
;
ei ; interrupts back on now
;
; port is considered inactive if values read from different port
; read mechanisms differ or if the value $FF is read consistently,
; or if the value read is equal to the port number itself
;
pop bc ; second IN0 (port) value
pop af ; first IN0 (port) valule
cp b ; same?
pop bc ; IN (C) value
jr nz,ISPORT ; if no, active running ctr port
cp b ; same?
jr nz,NEXTPT ; if not, inactive port
cp 0FFh ; pullup value???
jr z,NEXTPT ; if so, consider not active
cp d ; value same as port num???
jr z,NEXTPT ; if so, consider not active
;
.8080
ISPORT:
mov a,d ; got a live one, probably
ani 0f0h ; is port in same group as last ?
cmp e
jz nocrlf
call type ; no, start a new line
dw crlfe
mov a,d ; save for next time
ani 0f0h
mov e,a
nocrlf:
MOV A,D ; Get port #
PUSH D
PUSH H
HEXOUT
POP H
POP D
INX H ; count another one found
call type
db ' '+eol
NEXTPT:
INR D ; Bump port counter
JNZ PORTLP ; Not done
CALL TYPE ; Done
DW CRLFE
CALL BINDEC
CALL TYPE ; Type Active Ports
DB ' Ports active'
DW CRLFE
CCP:
LHLD OLDSP
SPHL
RET
;***********************;
; SUBROUTINES ;
;***********************;
;Binary to decimal conversion
BINDEC:
DECOUT ; From LIB
RET
;Types a string of text terminated with bit 7 high
TYPE:
XTHL ; Get string address
PUSH D
TYPELP:
MOV A,M ; Get type data
MOV D,A ; Save for later
ANI 7FH ; Mask ASCII
MOV E,A
PUSH H
PUSH D
CALL TCHR
POP D
POP H
INX H
MVI A,EOL ; End of line bit
ANA D
JP TYPELP ; Not done
POP D
XTHL ; Get return address
RET
;Types a single character on console
TCHR:
MVI C,2
JMP BDOS
;Checks sectors per block and multiplies or divides block size
;Enter with data in D. Result returned in H,L
;
SHF16:
LDA BLKSHF ; Get shift factor (gives block size)
CPI 3 ; Is it 1K (std)?
JNZ NOT3
MOV L,E ; Yes, use present #
ZH:
MVI H,0
RET
;
NOT3:
CPI 2 ; Is it minifloppy?
JNZ NOT2
MOV A,E ; Yes, divide by 2
RRC
ANI 7FH
MOV L,A
JMP ZH
NOT2:
SUI 3 ; Must be something
MOV B,A ; larger like double
XCHG ; sided or double dens
BITSHF:
DAD H ; 16 bit 2^(B-1)
DCR B
JNZ BITSHF
RET
;***********************;
; DATA STORAGE ;
;***********************;
FCB: DB 0,'???????????',0,0,0 ; File control block
DS 17 ; Extra FCB workspace
OLDSP: DS 2 ; Old stack pointer
RAM: DS 2 ; RAM counter
ROM: DS 2 ; ROM counter
RAMF: DS 1 ; RAM good flag
EMPF: DS 1 ; Empty so far flag
BLKSHF: DS 1 ; block shift factor
MAXALL: DS 2 ; maximum block number
BANK: DS 1 ; saved HBIOS bank id
IS180: DS 1 ; non-zero for Z180 CPU
FINIS EQU $ ; End of program
;
.DEPHASE
;
IMGEND:
;
END


978
Source/Apps/SysCopy.asm

@ -1,978 +0,0 @@
;===============================================================================
; SysCopy - Copy System Image to/from reserved tracks of disk for RomWBW
; adaptation of CP/M 2.2 & CP/M 3
;===============================================================================
;
; Author: Wayne Warthen (wwarthen@gmail.com)
;_______________________________________________________________________________
;
; Usage:
; SYSCOPY <dest>[=<src>]
;
; <dest> and <src> may be a drive or a file reference
; If <src> is not specified, the system image will
; be read from the current drive
;_______________________________________________________________________________
;
; Change Log:
; 2016-04-24 [WBW] Updated to preserve MBR partition table
; 2020-02-17 [WBW] Updated for CP/M 3
;_______________________________________________________________________________
;
; ToDo:
; 1) Add option to wait/prompt for disk change
; 2) Allow <src> and <dest> to be memory
;_______________________________________________________________________________
;
;===============================================================================
; Definitions
;===============================================================================
;
false .equ 0 ; define true
true .equ ~false ; define false
;
stksiz .equ $40 ; we are a stack pig
;
restart .equ $0000 ; CP/M restart vector
bdos .equ $0005 ; BDOS invocation vector
;
imgbuf .equ $900 ; load point for system image (from original SYSGEN)
mbrbuf .equ imgbuf+$4000 ; load point for MBR storage
;
;===============================================================================
; Code Section
;===============================================================================
;
.org $100
; setup stack (save old value)
ld (stksav),sp ; save stack
ld sp,stack ; set new stack
; processing...
call main ; do the real work
call crlf ; formatting
; return
jp 0 ; return to CP/M via reset
;
;ld sp,(stksav) ; restore stack
;ret ; return to CP/M w/o reset
;
; Main routine
;
main:
call init ; initialize
ret nz ; abort on failure
call parse ; parse command tail
ret nz ; abort on failure
call confirm ; confirm pending action
ret nz ; abort on failure
call crlf ; formatting
ld de,msgrd
call prtstr ; display "reading" message
call rdimg ; do the image read
ret nz ; abort on failure
ld de,msgwrt
call prtstr ; display "writing" message
call wrtimg ; do the image write
ret nz ; abort on failure
ld de,msgdon ; completion message
call prtstr ; display it
ret
;
; Initialization
;
init:
; add check for RomWBW?
;
; get OS version
ld c,12 ; BDOS get os version
call bdos ; do it, L=version
cp $30 ; Test for v3.0
jr c,init1 ; if <, pre v3.0
ld a,true ; OS v3.0 or above
ld (v3os),a ; save it
jr init2
init1:
ld a,false ; OS < v3.0
ld (v3os),a ; save it
init2:
; locate cbios function table address
ld hl,(restart+1) ; load address of CP/M restart vector
ld de,-3 ; adjustment for start of table
add hl,de ; HL now has start of table
ld (cbftbl),hl ; save it
; save current drive no
ld c,$19 ; bdos func: get current drive
call bdos ; invoke BDOS function
inc a ; 1-based index for fcb
ld (defdrv),a ; save it
; print version banner
call crlf ; formatting
ld de,msgban1 ; point to version message part 1
call prtstr ; print it
ld a,(v3os) ; get OS version flag
or a ; set flags
ld de,msgv2 ; point to V2 mode message
call z,prtstr ; if V2, say so
ld de,msgv3 ; point to V3 mode message
call nz,prtstr ; if V3, say so
call crlf ; formatting
ld de,msgban2 ; point to version message part 2
call prtstr ; print it
call crlf ; formatting
; return success
xor a
ret
;
; Parse command tail
;
parse:
ld hl,$81 ; point to start of command tail (after length byte)
call nonblank ; locate start of parms
jp z,erruse ; no parms
ld de,destfcb ; point to destination fcb
call convert ; convert destination spec
jp nz,erramb ; Error, ambiguous file specification
call nonblank ; skip blanks
or a ; end of command tail (null)?
jr z,parse2 ; setup default source fcb
cp '=' ; std delimiter
jr z,parse1 ; valid delimiter, continue
cp '_' ; alt delimiter
jr z,parse1 ; valid delimiter, continue
jp errdlm ; invalid delimiter
parse1:
inc hl ; skip delimiter
call nonblank ; skip blanks
parse2:
ld de,srcfcb ; point to source fcb
call convert ; convert spec to fcb
jp nz,erramb ; Error, ambiguous file specification
; return success
xor a ; signal success
ret ; done parsing
;
; Confirm pending action with user
;
confirm:
; prompt
call crlf
ld de,sconf1
call prtstr
ld hl,srcfcb
call prtfcb
ld de,sconf2
call prtstr
ld hl,destfcb
call prtfcb
ld de,sconf3
call prtstr
;
; get input (imgbuf is used for temp storage)
ld c,$0A ; get console buffer
ld de,imgbuf ; into buf
ld a,1 ; max of 1 character
ld (de),a ; set up buffer
call bdos ; invoke BDOS
ld a,(imgbuf+1) ; get num chars entered
dec a ; check that we got exactly one char
jr nz,confirm ; bad input, re-prompt
ld a,(imgbuf+2) ; get the character
and $DF ; force upper case
cp 'Y' ; compare to Y
ret ; return with Z set appropriately
;
; Read system image
;
rdimg:
ld hl,srcfcb ; point to source fcb
call chkfcb ; check if for drive/file spec
bit 1,a ; is there a file spec?
jp nz,rdfil ; yes, read using file i/o
jp rddsk ; no, read using raw disk i/o
;
; Write system image
;
wrtimg:
ld hl,destfcb ; point to destination fcb
call chkfcb ; check it for drive/file spec
bit 1,a ; is there a file spec?
jp nz,wrfil ; yes, write using file i/o
jp wrdsk ; no, write using raw disk i/o
;
; Read system image from file system
;
rdfil:
; open the file
ld c,$0F ; bdos open file
ld de,srcfcb ; source fcb
ld (rwfcb),de ; save it
call bdos ; invoke bdos function
cp $FF ; $FF is error
jp z,errfil ; handle error condition
; read the header
ld a,$14 ; setup for bdos read sequential
ld (rwfun),a ; save bdos function
ld a,12 ; start with 1536 byte header (12 records)
ld (reccnt),a ; init record counter
ld hl,imgbuf ; start of buffer
ld (bufptr),hl ; init buffer pointer
call rwfil ; read the header
ret nz ; abort on error (no need to close file)
; check header and get image size
call chkhdr ; verifies marker & ver, hl = image size
ret nz ; abort on error (no need to close file)
ld b,7 ; right shift 7 bits to get 128 byte record count
rdfil1: srl h ; shift right msb
rr l ; shift lsb w/ carry from msb
djnz rdfil1 ; loop till done
ld a,l ; record count to a
ld (reccnt),a ; set remaining records to read
add a,12 ; add the header back
ld (imgsiz),a ; and save the total image size (in records)
call rwfil ; do it
ret nz ; abort on error
; return via close file
jp closefile ; close file
;
; Write system image to file system
;
wrfil:
; check for pre-existing target file
ld c,$11 ; bdos find first
ld de,destfcb ; destination fcb
call bdos
cp $FF ; check for error
jr z,wrfil1 ; not there, skip delete
; delete target file if it exists
ld c,$13 ; bdos delete
ld de,destfcb ; destination fcb
call bdos
cp $FF ; check return code
jp z,errdel ; handle error
wrfil1: ; create target file
ld c,$16 ; bdos create file
ld de,destfcb ; destination fcb
ld (rwfcb),de ; save it
call bdos
cp $FF ; check return code
jp z,errfil ; handle error
; write the image
ld a,$15 ; setup for bdos write sequential
ld (rwfun),a ; save bdos function
ld a,(imgsiz) ; number of records to write
ld (reccnt),a ; init record counter
ld hl,imgbuf ; start of buffer
ld (bufptr),hl ; init buffer pointer
call rwfil ; do it
ret nz ; abort on error
; return via close file
jp closefile ; close file
;
; Common routine to handle read/write for file system
;
rwfil:
ld c,$1A ; BDOS set dma
ld de,(bufptr) ; current buffer pointer
push de ; save pointer
call bdos ; do it
pop de ; recover pointer
ld hl,128 ; record length
add hl,de ; increment buffer pointer
ld (bufptr),hl ; save it
ld a,(rwfun) ; get the active function
ld c,a ; set it
ld de,(rwfcb) ; active fcb
call bdos ; do it
or a ; check return code
jp nz,errdos ; BDOS err
ld hl,reccnt ; point to record count
dec (hl) ; decrement record count
jr nz,rwfil ; loop till done
xor a ; signal success
ret ; done
;
; Close file
;
closefile:
ld c,$10 ; BDOS close file
ld de,(rwfcb) ; active fcb
call bdos ; do it
cp $FF ; $FF is error
jp z,errclo ; if error, handle it
xor a ; signal success
ret ; done
;
; Read image directly from disk system tracks using CBIOS
;
rddsk:
; force return to go through disk reset
ld hl,resdsk ; load address of reset disk routine
push hl ; and put it on the stack
; set drive for subsequent reads
ld a,(srcfcb) ; get the drive
dec a ; adjust for zero indexing
call setdsk ; setup disk
ret nz ; abort on error
; set function to read
ld a,13 ; CBIOS func 13: Read
ld (actfnc),a ; save it
; read the header
ld a,12 ; start with 1536 byte header (12 records)
ld (reccnt),a ; initialize record counter
call rwdsk ; read the header
ret nz ; abort on error
; check header and get image size
call chkhdr ; check integrity, HL = image size on return
ret nz ; abort on error
; convert image size to count of 128-byte records
ld b,7 ; right shift 7 bits to get 128 byte record count
rddsk1: srl h ; shift right msb
rr l ; shift lsb w/ carry from msb
djnz rddsk1 ; loop till done
; set the number of records pending to read
ld a,l ; record count to a
ld (reccnt),a ; set remaining records to read
; save the total image size (including header) for later
add a,12 ; add the header records back
ld (imgsiz),a ; and save the total image size (in records)
; read the remaining system image records
call rwdsk ; finish up
ret nz ; abort on error
; perform BDOS disk reset (critical since we mucked with CBIOS)
ld c,$0D ; BDOS reset disk
call bdos ; do it
; return
xor a ; signal success
ret ; done
;
; Write image directly to disk system tracks using CBIOS
;
wrdsk:
; force return to go through disk reset
ld hl,resdsk ; load address of reset disk routine
push hl ; and put it on the stack
; setup to read existing MBR
ld a,(destfcb) ; get the drive
dec a ; adjust for zero indexing
call setdsk ; setup disk
ret nz ; abort on error
ld hl,mbrbuf ; override to read
ld (bufptr),hl ; ... into MBR buffer
ld a,4 ; 4 records = 1 512 byte sector
ld (reccnt),a ; initialize record counter
; set function to read
ld a,13 ; CBIOS func 13: Read
ld (actfnc),a ; save it
; read the existing MBR into memory
call rwdsk ; read the sector
ret nz ; abort on error
; test for valid partition table ($55, $AA at offset $1FE)
ld hl,(mbrbuf+$1FE); HL := signature
ld a,$55 ; load expected value of first byte
cp l ; check for proper value
jr nz,wrdsk1 ; mismatch, ignore old partition table
ld a,$AA ; load expected value of second byte
cp h ; check for proper value
jr nz,wrdsk1 ; mismatch, ignore old partition table
; valid MBR, copy existing partition table over to new image
ld hl,mbrbuf+$1BE ; copy from MBR offset of existing MBR
ld de,imgbuf+$1BE ; copy to MBR offset of new image
ld bc,$40 ; size of MBR
ldir ; do it
wrdsk1: ; setup to write the image from memory to disk
ld a,(destfcb) ; get the drive
dec a ; adjust for zero indexing
call setdsk ; setup disk
ret nz ; abort on error
; set function to write
ld a,14 ; CBIOS func 14: Write
ld (actfnc),a ; save it
; setup the record count to write
ld a,(imgsiz) ; get previously recorded image size
ld (reccnt),a ; save it as pending record count
; write the image
call rwdsk ; write the image
ret nz ; abort on error
; return
xor a ; signal success
ret ; done
;
; Perform BDOS disk reset
; Required after making direct CBIOS disk calls
;
resdsk:
; perform BDOS disk reset
push af ; preserve status
ld c,$0D ; BDOS reset disk
call bdos ; do it
pop af ; restore status
ret
;
; Setup for CBIOS disk access
;
setdsk:
; select disk
ld (actdsk),a ; save active disk no
ld c,a ; move to c
ld e,0 ; treat as first select
call cbios ; invoke cbios with...
;.db $1B ; SELDSK entry offset
.db 9 ; SELDSK entry offset
; check return (sets HL to DPH address)
ld a,h
or l
jp z,errsel ; HL == 0 is select error
; set HL to DPB address
ld de,10 ; DPB address is 10 bytes into DPH
add hl,de ; HL := address of DPB pointer
ld a,(hl) ; dereference...
inc hl
ld h,(hl)
ld l,a ; HL := address of DPB
; extract sectors per track from first word of DPB
ld c,(hl)
inc hl
ld b,(hl) ; BC := sectors per track
ld (actspt),bc ; save it
; ensure there are system tracks (verify that offset field in DPB is not zero)
ld de,12 ; offset field is 12 bytes into DPB
add hl,de ; point to offset field in DPB
ld a,(hl) ; load first byte in A
inc hl ; point to second byte
or (hl) ; or with first byte
jp z,errsys ; if zero, abort (no system tracks)
; initialize for I/O
ld hl,0
ld (acttrk),hl ; active track := 0
ld (actsec),hl ; active sector := 0
ld hl,imgbuf ; assume r/w to image buffer
ld (bufptr),hl ; reset buffer pointer
;
xor a ; signal success
ret ; done
;
; Read or write (reccnt) sectors to/from disk via CBIOS
;
rwdsk:
ld hl,128 ; assume rec len for < CP/M 3
ld (reclen),hl ; and save it
ld a,(v3os) ; CP/M 3 or greater?
or a ; set flags
jr z,rwdsk0 ; if not, continue
; adjust reccnt, logical (128) to physical (512)
ld a,(reccnt) ; get pending rec cnt
add a,3 ; round up
srl a ; shift to
srl a ; ... divide by 4
ld (reccnt),a ; and resave it
ld hl,512 ; use physical rec len
ld (reclen),hl ; and save it
rwdsk0:
; setup to read/write a sector
ld bc,(acttrk) ; get active track
call cbios ; invoke cbios with...
;.db $1E ; SETTRK entry offset
.db 10 ; SETTRK entry offset
ld bc,(actsec) ; get active sector
call cbios ; invoke cbios with...
;.db $21 ; SETSEC entry offset
.db 11 ; SETSEC entry offset
ld bc,(bufptr) ; get active buffer pointer
call cbios ; invoke cbios with...
;.db $24 ; SETDMA entry offset
.db 12 ; SETDMA entry offset
; read/write sector
ld a,(reccnt) ; get the pending record count
dec a ; last record?
ld c,2 ; allow cached writes by default
jr nz,rwdsk1 ; not last record, continue
ld c,1 ; last record, no caching please
rwdsk1:
ld a,(actfnc)
call cbiosfn
or a ; set flags on return code
jp nz,errio ; if not zero, error abort
; adjust buffer pointer
ld hl,(bufptr) ; get buffer pointer
ld de,(reclen) ; get rec len
add hl,de ; adjust buffer ptr for next record
ld (bufptr),hl ; save it
; next sector
ld hl,(actsec) ; current sector
inc hl ; increment sector
ld (actsec),hl ; save it
; check for end of track
ld de,(actspt) ; get current sectors per track
or a ; clear CF
sbc hl,de ; current track == sectors per track?
jr nz,rwdsk2 ; no, skip track change
; next track
ld hl,0
ld (actsec),hl ; current sector := 0
ld hl,acttrk ; point to track variable
inc (hl) ; increment track
; check pending record count and loop or return
rwdsk2: ld hl,reccnt
dec (hl) ; decrement pending record count
ret z ; if zero, done, return with Z set
jr rwdsk0 ; otherwise, loop
;
jphl: jp (hl) ; indirect jump
;
; Verify system image header in buf by checking the expected signature.
; Compute and return image size (based on header values) in HL.
; NZ set if signature error.
;
chkhdr:
; check signature
ld hl,(imgbuf+$580) ; get signature
ld de,$A55A ; signature value
or a ; clear CF
sbc hl,de ; compare
jp nz,errsig ; invalid signature
; compute the image size (does not include size of header)
ld hl,(imgbuf+$5FC) ; get CPM_END
ld de,(imgbuf+$5FA) ; get CPM_LOC
or a ; clear CF
sbc hl,de ; image size := CPM_END - CPM_LOC
xor a ; signal success
ret ; done
;
; Convert a filename at (HL) into an FCB at (DE).
; Includes wildcard expansion.
; On return, A=0 if unambiguous name specified, and
; (HL) points to character following filename spec
;
convert:
push de ; put fcb address on stack
ex de,hl
ld a,(de) ; get first character.
or a
jp z,convrt1
sbc a,'A'-1 ; might be a drive name, convert to binary.
ld b,a ; and save.
inc de ; check next character for a ':'.
ld a,(de)
cp ':'
jp z,convrt2
dec de ; nope, move pointer back to the start of the line.
convrt1:
ld a,(defdrv)
ld (hl),a
jp convrt3
convrt2:
ld a,b
ld (hl),b
inc de
; Convert the base file name.
convrt3:ld b,08h
convrt4:ld a,(de)
call delim
jp z,convrt8
inc hl
cp '*' ; note that an '*' will fill the remaining
jp nz,convrt5 ; field with '?'
ld (hl),'?'
jp convrt6
convrt5:ld (hl),a
inc de
convrt6:dec b
jp nz,convrt4
convrt7:ld a,(de)
call delim ; get next delimiter
jp z,getext
inc de
jp convrt7
convrt8:inc hl ; blank fill the file name
ld (hl),' '
dec b
jp nz,convrt8
getext: ld b,03h
cp '.'
jp nz,getext5
inc de
getext1:ld a,(de)
call delim
jp z,getext5
inc hl
cp '*'
jp nz,getext2
ld (hl),'?'
jp getext3
getext2:ld (hl),a
inc de
getext3:dec b
jp nz,getext1
getext4:ld a,(de)
call delim
jp z,getext6
inc de
jp getext4
getext5:inc hl
ld (hl),' '
dec b
jp nz,getext5
getext6:ld b,3
getext7:inc hl
ld (hl),0
dec b
jp nz,getext7
pop hl ; HL := start of FCB
push de ; save input line pointer
; Check to see if this is an ambiguous file name specification.
; Set the A register to non-zero if it is.
ld bc,11 ; set name length.
getext8:inc hl
ld a,(hl)
cp '?' ; any question marks?
jp nz,getext9
inc b ; count them.
getext9:dec c
jp nz,getext8
ld a,b
or a
pop hl ; return with updated input pointer
ret
;
; Print formatted FCB at (HL)
;
prtfcb:
push hl ; save HL
call chkfcb ; set flags indicating nature of FCB
pop hl ; restore HL
ret z ; nothing to print
push af ; save FCB flags
ld a,(hl) ; get first byte of FCB (drive)
inc hl ; point to next char
or a ; is drive specified (non-zero)?
jr z,prtfcb1 ; if zero, do not print drive letter
add a,'@' ; adjust drive number to alpha
call prtchr ; print it
ld a,':'
call prtchr ; print drive separator
prtfcb1:
pop af ; restore FCB flags
bit 1,a ; bit 1 set if filename specified
ret z ; return if no filename
ld b,8 ; base is 8 characters
call prtfcb2 ; print them
ld a,'.'
call prtchr ; print file extension separator
ld b,3 ; extension is 3 characters
prtfcb2:
ld a,(hl) ; load the next character
inc hl ; point to next character
cp ' ' ; check for blank
call nz,prtchr ; print char if it is not a blank
djnz prtfcb2 ; loop till done
ret ; return
;
; Check FCB to see if a drive and/or filename is specified.
; Set bit 0 for drive and bit 1 for filename in A
;
chkfcb:
ld c,0 ; use C for flags, start with none
ld a,(hl) ; get drive
or a ; anything there?
jr z,chkfcb1 ; skip if nothing there
set 0,c ; set bit zero to indicate a drive spec
chkfcb1:
ld b,11 ; set up to check 11 bytes (base & ext)
chkfcb2:
inc hl ; bump to next byte
ld a,(hl) ; get next
cp 'A' ; blank means empty byte
jr nc,chkfcb3 ; if not blank, we have a filename
djnz chkfcb2 ; loop
jr chkfcb4 ; nothing there
chkfcb3:
set 1,c ; set bit 1 to indicate a file spec
chkfcb4:
ld a,c ; put result in a
or a ; set flags
ret
;
; Print dot
;
prtdot:
push af
ld a,'.'
call prtchr
pop af
ret
;
; Print character in A without destroying any registers
;
prtchr:
push bc ; save registers
push de
push hl
ld e,a ; character to print in E
ld c,$02 ; BDOS function to output a character
call bdos ; do it
pop hl ; restore registers
pop de
pop bc
ret
;
; Print $ terminated string at (DE) without destroying any registers
;
prtstr:
push bc ; save registers
push de
push hl
ld c,$09 ; BDOS function to output a '$' terminated string
call bdos ; do it
pop hl ; restore registers
pop de
pop bc
ret
;
; Print the value in A in hex without destroying any registers
;
prthex:
push af ; save AF
push de ; save DE
call hexascii ; convert value in A to hex chars in DE
ld a,d ; get the high order hex char
call prtchr ; print it
ld a,e ; get the low order hex char
call prtchr ; print it
pop de ; restore DE
pop af ; restore AF
ret ; done
;
; Convert binary value in A to ascii hex characters in DE
;
hexascii:
ld d,a ; save A in D
call hexconv ; convert low nibble of A to hex
ld e,a ; save it in E
ld a,d ; get original value back
rlca ; rotate high order nibble to low bits
rlca
rlca
rlca
call hexconv ; convert nibble
ld d,a ; save it in D
ret ; done
;
; Convert low nibble of A to ascii hex
;
hexconv:
and $0F ; low nibble only
add a,$90
daa
adc a,$40
daa
ret
;
; Start a new line
;
crlf:
ld a,13 ; <CR>
call prtchr ; print it
ld a,10 ; <LF>
jr prtchr ; print it
;
; Get the next non-blank character from (HL).
;
nonblank:
ld a,(hl) ; load next character
or a ; string ends with a null
ret z ; if null, return pointing to null
cp ' ' ; check for blank
ret nz ; return if not blank
inc hl ; if blank, increment character pointer
jr nonblank ; and loop
;
; Check character at (DE) for delimiter.
;
delim: or a
ret z
cp ' ' ; blank
ret z
jr c,delim1 ; handle control characters
cp '=' ; equal
ret z
cp '_' ; underscore
ret z
cp '.' ; period
ret z
cp ':' ; colon
ret z
cp $3b ; semicolon
ret z
cp '<' ; less than
ret z
cp '>' ; greater than
ret
delim1:
; treat control chars as delimiters
xor a ; set Z
ret ; return
;
; Invoke CBIOS function
; The CBIOS function offset must be stored in the byte
; following the call instruction. ex:
; call cbios
; .db $0C ; offset of CONOUT CBIOS function
;
cbios:
ex (sp),hl
ld a,(hl) ; get the function number
inc hl ; point past value following call instruction
ex (sp),hl ; put address back at top of stack and recover HL
cbiosfn:
; enter here if function already in reg A
ld (bpb_fn),a ; save function
;
ld a,(v3os) ; CP/M 3 or greater?
or a ; set flags
jr nz,cbios2 ; if >= V3, handle it
;
; CBIOS call for CP/M < v3
ld a,(bpb_fn) ; get pending function number
ld l,a ; function number to L
add a,l ; ... and multiply by 3 for
add a,l ; ... jump table offset
ld hl,(cbftbl) ; address of CBIOS function table to HL
call addhl ; determine specific function address
jp (hl) ; invoke CBIOS
;
cbios2:
; CBIOS call for CP/M v3 or greater
ld (bpb_bc),bc
ld (bpb_de),de
ld (bpb_hl),hl
ld c,50 ; direct bios call function number
ld de,bpb ; BIOS parameter block
jp bdos ; return via BDOS call
;
; Add the value in A to HL (HL := HL + A)
;
addhl:
add a,l ; A := A + L
ld l,a ; Put result back in L
ret nc ; if no carry, we are done
inc h ; if carry, increment H
ret ; and return
;
; Errors
;
erruse: ; command usage error (syntax)
ld de,msguse
jr err
erramb: ; ambiguous file spec (wild cards) is not allowed
ld de,msgamb
jr err
errdlm: ; invalid delimiter in command tail
ld de,msgdlm
jr err
errfil: ; source file not found
ld de,msgfil
jr err
errclo: ; file close error
ld de,msgclo
jr err
errdel: ; file delete error
ld de,msgdel
jr err
errsig: ; invalid system image signature error
ld de,msgsig
jr err
errsel: ; CBIOS drive select error
ld de,msgsel
jr err
errsys: ; no system tracks on drive error
ld de,msgsys
jr err
errio: ; I/O error
ld de,msgio
jr err
err: ; print error string and return error signal
call crlf ; print newline
call prtstr ; print error string
or $FF ; signal error
ret ; done
errdos: ; handle BDOS errors
push af ; save return code
call crlf ; newline
ld de,msgdos ; load
call prtstr ; and print error string
pop af ; recover return code
call prthex ; print error code
or $FF ; signal error
ret ; done
;
;===============================================================================
; Storage Section
;===============================================================================
;
defdrv .db 0 ; default drive for FCB
cbftbl .dw 0 ; address of CBIOS function table
imgsiz .db 0 ; image size (count of 128 byte records)
;
destfcb .fill 36,0 ; destination FCB
srcfcb .fill 36,0 ; source FCB
;
stksav .dw 0 ; stack pointer saved at start
.fill stksiz,0 ; stack
stack .equ $ ; stack top
;
rwfun .db 0 ; active read/write function
rwfcb .dw 0 ; active read/write FCB
reccnt .db 0 ; active remaining records to read/write
bufptr .dw 0 ; active pointer into buffer
;
actdsk .db 0 ; active disk no
acttrk .dw 0 ; active track
actsec .dw 0 ; active sector
actspt .dw 0 ; active sectors per track
actfnc .db 0 ; active cbios i/o function (read or write)
v3os .db 0 ; true ($FF) if OS v3.0 or greater
reclen .dw 0 ; active record length
;
bpb: ; BIOS parameter block for CP/M 3 BIOS calls
bpb_fn .db 0 ; function
bpb_a .db 0 ; reg A
bpb_bc .dw 0 ; reg BC
bpb_de .dw 0 ; reg DE
bpb_hl .dw 0 ; reg HL
;
; Messages
;
msgban1 .db "SYSCOPY v2.0 for RomWBW CP/M, 17-Feb-2020$"
msgv2 .db " (CP/M 2 Mode)$"
msgv3 .db " (CP/M 3 Mode)$"
msgban2 .db "Copyright 2020, Wayne Warthen, GNU GPL v3$"
msguse .db "Usage: SYSCOPY <dest>[=<source>]$"
msgamb .db "Ambiguous file specification not allowed$"
msgdlm .db "Invalid delimiter$"
msgfil .db "File not found$"
msgclo .db "File close error$"
msgdel .db "Error deleting target file$"
msgsig .db "Invalid system image (bad signature)$"
msgdos .db "DOS error, return code=0x$"
msgsel .db "Disk select error$"
msgsys .db "Non-system disk error$"
msgio .db "Disk I/O error$"
msgrd .db "Reading image... $"
msgwrt .db "Writing image... $"
msgdon .db "Done$"
sconf1 .db "Transfer system image from $"
sconf2 .db " to $"
sconf3 .db " (Y/N)? $"
;
.end

507
Source/Apps/SysGen.z80

@ -1,507 +0,0 @@
TITLE 'SYSGEN - SYSTEM GENERATION PROGRAM 8/79'
; SYSTEM GENERATION PROGRAM, VERSION FOR ROMWBW
VERS EQU 20 ; X.X
;
; COPYRIGHT (C) DIGITAL RESEARCH
; 1976, 1977, 1978, 1979
;
NDISKS EQU 16 ; NUMBER OF DISK DRIVES
SECSIZ EQU 128 ; SIZE OF EACH SECTOR
LOG2SEC EQU 7 ; LOG 2 SECSIZ
;
FCB EQU 05CH ; DEFAULT FCB LOCATION
FCBCR EQU FCB+32 ; CURRENT RECORD LOCATION
TPA EQU 0100H ; TRANSIENT PROGRAM AREA
LOADP EQU 900H ; LOAD POINT FOR SYSTEM DURING LOAD/STORE
BDOS EQU 5 ; DOS ENTRY POINT
BOOT EQU 0 ; JMP TO 'BOOT' TO REBOOT SYSTEM
CONI EQU 1 ; CONSOLE INPUT FUNCTION
CONO EQU 2 ; CONSOLE OUTPUT FUNCTION
OPENF EQU 15 ; DISK OPEN FUNCTION
DREADF EQU 20 ; DISK READ FUNCTION
;
CR EQU 0DH ; CARRIAGE RETURN
LF EQU 0AH ; LINE FEED
STKSIZE EQU 16 ; SIZE OF LOCAL STACK
;
WBOOT EQU 1 ; ADDRESS OF WARM BOOT (OTHER PATCH ENTRY
;
ORG TPA ; TRANSIENT PROGRAM AREA
JP START
DB 'COPYRIGHT (C) 1978, DIGITAL RESEARCH '
;
; UTILITY SUBROUTINES
;
GETCHAR:
; READ CONSOLE CHARACTER TO REGISTER A
LD C,CONI
CALL BDOS
; CONVERT TO UPPER CASE BEFORE RETURN
CP 'A' OR 20H
RET C ; RETURN IF BELOW LOWER CASE A
CP ('Z' OR 20H) + 1
RET NC ; RETURN IF ABOVE LOWER CASE Z
AND 5FH
RET
;
PUTCHAR:
; WRITE CHARACTER FROM A TO CONSOLE
LD E,A
LD C,CONO
CALL BDOS
RET
;
CRLF: ; SEND CARRIAGE RETURN, LINE FEED
LD A,CR
CALL PUTCHAR
LD A,LF
CALL PUTCHAR
RET
;
CRMSG: ; PRINT MESSAGE ADDRESSED BY H,L TIL ZERO
; WITH LEADING CRLF
PUSH HL
CALL CRLF
POP HL ; DROP THRU TO OUTMSG0
OUTMSG:
LD A,(HL)
OR A
RET Z
; MESSAGE NOT YET COMPLETED
PUSH HL
CALL PUTCHAR
POP HL
INC HL
JP OUTMSG
;
DREAD: ; DISK READ FUNCTION VIA BDOS
LD C,DREADF
JP BDOS
;
OPEN: ; FILE OPEN FUNCTION VIA BDOS
LD C,OPENF
JP BDOS
;
; READ IMAGE DIRECTLY FROM DISK SYSTEM TRACKS USING CBIOS
; DISK NUMBER MUST BE IN (ACTDSK)
;
RDDSK:
; FORCE RETURN TO GO THROUGH DISK RESET
LD HL,RESDSK ; LOAD ADDRESS OF RESET DISK ROUTINE
PUSH HL ; AND PUT IT ON THE STACK
; SET DRIVE FOR SUBSEQUENT READS
CALL SETDSK ; SETUP DISK SPECIFIED IN A
RET NZ ; ABORT ON ERROR
; SET FUNCTION TO READ
LD HL,(CBFTBL) ; GET ADDRESS OF CBIOS FUNCTION TABLE
LD A,027H ; $27 IS CBIOS READ ENTRY OFFSET
CALL ADDHL ; SET HL TO RESULTANT ENTRY POINT
LD (ACTFNC),HL ; SAVE IT
; READ THE HEADER
LD A,12 ; START WITH 1536 BYTE HEADER (12 RECORDS)
LD (RECCNT),A ; INITIALIZE RECORD COUNTER
CALL RWDSK ; READ THE HEADER
RET NZ ; ABORT ON ERROR
; CHECK HEADER AND GET IMAGE SIZE
CALL CHKHDR ; CHECK INTEGRITY, HL = IMAGE SIZE ON RETURN
RET NZ ; ABORT ON ERROR
; CONVERT IMAGE SIZE TO COUNT OF 128-BYTE RECORDS
LD B,7 ; RIGHT SHIFT 7 BITS TO GET 128 BYTE RECORD COUNT
RDDSK1: SRL H ; SHIFT RIGHT MSB
RR L ; SHIFT LSB W/ CARRY FROM MSB
DJNZ RDDSK1 ; LOOP TILL DONE
; SET THE NUMBER OF RECORDS PENDING TO READ
LD A,L ; RECORD COUNT TO A
LD (RECCNT),A ; SET REMAINING RECORDS TO READ
; SAVE THE TOTAL IMAGE SIZE (INCLUDING HEADER) FOR LATER
ADD A,12 ; ADD THE HEADER RECORDS BACK
LD (IMGSIZ),A ; AND SAVE THE TOTAL IMAGE SIZE (IN RECORDS)
; READ THE REMAINING SYSTEM IMAGE RECORDS
CALL RWDSK ; FINISH UP
RET NZ ; ABORT ON ERROR
; PERFORM BDOS DISK RESET (CRITICAL SINCE WE MUCKED WITH CBIOS)
LD C,0DH ; BDOS RESET DISK
CALL BDOS ; DO IT
; RETURN
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
; WRITE IMAGE DIRECTLY TO DISK SYSTEM TRACKS USING CBIOS
; DISK NUMBER MUST BE IN (ACTDSK)
;
WRDSK:
; FORCE RETURN TO GO THROUGH DISK RESET
LD HL,RESDSK ; LOAD ADDRESS OF RESET DISK ROUTINE
PUSH HL ; AND PUT IT ON THE STACK
; SET DRIVE FOR SUBSEQUENT WRITES
CALL SETDSK ; SETUP DISK SPECIFIED IN A
RET NZ ; ABORT ON ERROR
; SET FUNCTION TO WRITE
LD HL,(CBFTBL) ; GET ADDRESS OF CBIOS FUNCTION TABLE
LD A,02AH ; $2A IS CBIOS WRITE ENTRY OFFSET
CALL ADDHL ; SET HL TO RESULTANT ENTRY POINT
LD (ACTFNC),HL ; SAVE IT
; SETUP THE RECORD COUNT TO WRITE
LD A,(IMGSIZ) ; GET PREVIOUSLY RECORDED IMAGE SIZE
LD (RECCNT),A ; SAVE IT AS PENDING RECORD COUNT
; WRITE THE IMAGE
CALL RWDSK ; WRITE THE IMAGE
RET NZ ; ABORT ON ERROR
; RETURN
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
; PERFORM BDOS DISK RESET
; REQUIRED AFTER MAKING DIRECT CBIOS DISK CALLS
;
RESDSK:
; PERFORM BDOS DISK RESET
PUSH AF ; PRESERVE STATUS
LD C,0DH ; BDOS RESET DISK
CALL BDOS ; DO IT
POP AF ; RESTORE STATUS
RET
;
; SETUP FOR CBIOS DISK ACCESS
;
SETDSK:
; SELECT DISK
LD A,(ACTDSK) ; GET ACTIVE DISK
LD C,A ; MOVE TO C
LD E,0 ; TREAT AS FIRST SELECT
CALL CBIOS ; INVOKE CBIOS WITH...
DB 01BH ; SELDSK ENTRY OFFSET
; CHECK RETURN (SETS HL TO DPH ADDRESS)
LD A,H
OR L
JP Z,ERRSEL ; HL == 0 IS SELECT ERROR
; SET HL TO DPB ADDRESS
LD DE,10 ; DPB ADDRESS IS 10 BYTES INTO DPH
ADD HL,DE ; HL := ADDRESS OF DPB POINTER
LD A,(HL) ; DEREFERENCE...
INC HL
LD H,(HL)
LD L,A ; HL := ADDRESS OF DPB
; EXTRACT SECTORS PER TRACK FROM FIRST WORD OF DPB
LD C,(HL)
INC HL
LD B,(HL) ; BC := SECTORS PER TRACK
LD (ACTSPT),BC ; SAVE IT
; ENSURE THERE ARE SYSTEM TRACKS (VERIFY THAT OFFSET FIELD IN DPB IS NOT ZERO)
LD DE,12 ; OFFSET FIELD IS 12 BYTES INTO DPB
ADD HL,DE ; POINT TO OFFSET FIELD IN DPB
LD A,(HL) ; LOAD FIRST BYTE IN A
INC HL ; POINT TO SECOND BYTE
OR (HL) ; OR WITH FIRST BYTE
JP Z,ERRSYS ; IF ZERO, ABORT (NO SYSTEM TRACKS)
; INITIALIZE FOR I/O
LD HL,0
LD (ACTTRK),HL ; ACTIVE TRACK := 0
LD (ACTSEC),HL ; ACTIVE SECTOR := 0
LD HL,LOADP
LD (BUFPTR),HL ; RESET BUFFER POINTER
;
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
; READ OR WRITE (RECCNT) SECTORS TO/FROM DISK VIA CBIOS
;
RWDSK:
; SETUP TO READ/WRITE A SECTOR
LD BC,(ACTTRK) ; GET ACTIVE TRACK
CALL CBIOS ; INVOKE CBIOS WITH...
DB 01EH ; SETTRK ENTRY OFFSET
LD BC,(ACTSEC) ; GET ACTIVE SECTOR
CALL CBIOS ; INVOKE CBIOS WITH...
DB 021H ; SETSEC ENTRY OFFSET
LD BC,(BUFPTR) ; GET ACTIVE BUFFER POINTER
CALL CBIOS ; INVOKE CBIOS WITH...
DB 024H ; SETDMA ENTRY OFFSET
; READ/WRITE SECTOR
LD A,(RECCNT) ; GET THE PENDING RECORD COUNT
DEC A ; LAST RECORD?
LD C,2 ; ALLOW CACHED WRITES BY DEFAULT
JR NZ,RWDSK1 ; NOT LAST RECORD, CONTINUE
LD C,1 ; LAST RECORD, NO CACHING PLEASE
RWDSK1: LD HL,(ACTFNC) ; LOAD THE CBIOS FUNCTION VECTOR
CALL JPHL ; INDIRECT CALL (READ OR WRITE)
OR A ; SET FLAGS ON RETURN CODE
JP NZ,ERRIO ; IF NOT ZERO, ERROR ABORT
; ADJUST BUFFER POINTER
LD HL,(BUFPTR) ; GET BUFFER POINTER
LD DE,128 ; RECORD LENGTH IS 128 BYTES
ADD HL,DE ; ADJUST BUFFER PTR FOR NEXT RECORD
LD (BUFPTR),HL ; SAVE IT
; NEXT SECTOR
LD HL,(ACTSEC) ; CURRENT SECTOR
INC HL ; INCREMENT SECTOR
LD (ACTSEC),HL ; SAVE IT
; CHECK FOR END OF TRACK
LD DE,(ACTSPT) ; GET CURRENT SECTORS PER TRACK
OR A ; CLEAR CF
SBC HL,DE ; CURRENT TRACK == SECTORS PER TRACK?
JR NZ,RWDSK2 ; NO, SKIP TRACK CHANGE
; NEXT TRACK
LD HL,0
LD (ACTSEC),HL ; CURRENT SECTOR := 0
LD HL,ACTTRK ; POINT TO TRACK VARIABLE
INC (HL) ; INCREMENT TRACK
; CHECK PENDING RECORD COUNT AND LOOP OR RETURN
RWDSK2: LD HL,RECCNT
DEC (HL) ; DECREMENT PENDING RECORD COUNT
RET Z ; IF ZERO, DONE, RETURN WITH Z SET
JR RWDSK ; OTHERWISE, LOOP
;
JPHL: JP (HL) ; INDIRECT JUMP
;
; VERIFY SYSTEM IMAGE HEADER IN BUF BY CHECKING THE EXPECTED SIGNATURE.
; COMPUTE AND RETURN IMAGE SIZE (BASED ON HEADER VALUES) IN HL.
; NZ SET IF SIGNATURE ERROR.
;
CHKHDR:
; CHECK SIGNATURE
LD HL,(LOADP+580H) ; GET SIGNATURE
LD DE,0A55AH ; SIGNATURE VALUE
OR A ; CLEAR CF
SBC HL,DE ; COMPARE
JP NZ,ERRSIG ; INVALID SIGNATURE
; COMPUTE THE IMAGE SIZE (DOES NOT INCLUDE SIZE OF HEADER)
LD HL,(LOADP+5FCH) ; GET CPM_END
LD DE,(LOADP+5FAH) ; GET CPM_LOC
OR A ; CLEAR CF
SBC HL,DE ; IMAGE SIZE := CPM_END - CPM_LOC
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
; INVOKE CBIOS FUNCTION
; THE CBIOS FUNCTION OFFSET MUST BE STORED IN THE BYTE
; FOLLOWING THE CALL INSTRUCTION. EX:
; CALL CBIOS
; DB 0CH ; OFFSET OF CONOUT CBIOS FUNCTION
;
CBIOS:
EX (SP),HL
LD A,(HL) ; GET THE FUNCTION OFFSET
INC HL ; POINT PAST VALUE FOLLOWING CALL INSTRUCTION
EX (SP),HL ; PUT ADDRESS BACK AT TOP OF STACK AND RECOVER HL
LD HL,(CBFTBL) ; ADDRESS OF CBIOS FUNCTION TABLE TO HL
CALL ADDHL ; DETERMINE SPECIFIC FUNCTION ADDRESS
JP (HL) ; INVOKE CBIOS
;
; ADD THE VALUE IN A TO HL (HL := HL + A)
;
ADDHL:
ADD A,L ; A := A + L
LD L,A ; PUT RESULT BACK IN L
RET NC ; IF NO CARRY, WE ARE DONE
INC H ; IF CARRY, INCREMENT H
RET ; AND RETURN
;
; START OF PROGRAM
;
START:
LD SP,STACK ; SET LOCAL STACK POINTER
LD HL,SIGNON
CALL CRMSG
; LOCATE CBIOS FUNCTION TABLE ADDRESS
LD HL,(BOOT+1) ; LOAD ADDRESS OF CP/M RESTART VECTOR
LD DE,-3 ; ADJUSTMENT FOR START OF TABLE
ADD HL,DE ; HL NOW HAS START OF TABLE
LD (CBFTBL),HL ; SAVE IT
; CHECK FOR DEFAULT FILE LOAD INSTEAD OF GET
LD A,(FCB+1); BLANK IF NO FILE
CP ' '
JP Z,GETSYS ; SKIP TO GET SYSTEM MESSAGE IF BLANK
LD DE,FCB ; TRY TO OPEN IT
CALL OPEN ;
INC A ; 255 BECOMES 00
JP NZ,RDOK ; OK TO READ IF NOT 255
; FILE NOT PRESENT, ERROR AND REBOOT
LD HL,NOFILE
CALL CRMSG
JP REBOOT
;
; FILE PRESENT - READ TO LOAD POINT
;
RDOK:
XOR A
LD (FCBCR),A; CURRENT RECORD = 0
; PRE-READ AREA FROM TPA TO LOADP
LD C,(LOADP-TPA)/SECSIZ
PRERD: ; PRE-READ FILE
PUSH BC ; SAVE COUNT
LD DE,FCB ; INPUT FILE CONTROL COUNT
CALL DREAD ; ASSUME SET TO DEFAULT BUFFER
POP BC ; RESTORE COUNT
OR A
JP NZ,BADRD ; CANNOT ENCOUNTER END-OF FILE
DEC C ; COUNT DOWN
JP NZ,PRERD ; FOR ANOTHER SECTOR
;
; SECTORS SKIPPED AT BEGINNING OF FILE
;
LD HL,LOADP
RDINP:
PUSH HL
LD B,H
LD C,L ; READY FOR DMA
CALL CBIOS ; INVOKE CBIOS WITH...
DB 024H ; SETDMA ENTRY OFFSET
LD DE,FCB ; READY FOR READ
CALL DREAD ;
POP HL ; RECALL DMA ADDRESS
OR A ; 00 IF READ OK
JP NZ,PUTSYS ; ASSUME EOF IF NOT.
; MORE TO READ, CONTINUE
LD DE,SECSIZ
ADD HL,DE ; HL IS NEW LOAD ADDRESS
JP RDINP
;
BADRD: ; EOF ENCOUNTERED IN INPUT FILE
LD HL,BADFILE
CALL CRMSG
JP REBOOT
;
GETSYS:
CALL CRLF
LD HL,ASKGET ; GET SYSTEM?
CALL CRMSG
CALL GETCHAR
CP CR
JP Z,PUTSYS ; SKIP IF CR ONLY
;
SUB 'A' ; NORMALIZE DRIVE NUMBER
CP NDISKS ; VALID DRIVE?
JP C,GETC ; SKIP TO GETC IF SO
; INVALID DRIVE NUMBER
CALL BADDISK
JP GETSYS ; TO TRY AGAIN
;
GETC:
; SELECT DISK GIVEN BY REGISTER A
ADD A,'A'
LD (GDISK),A; TO SET MESSAGE
SUB 'A'
LD (ACTDSK),A ; SAVE ACTIVE DISK NO
; ; GETSYS, SET RW TO READ AND GET THE SYSTEM
CALL CRLF
LD HL,GETMSG
CALL OUTMSG
CALL GETCHAR
CP CR
JP NZ,REBOOT
CALL CRLF
CALL RDDSK
JP NZ,GETSYS
LD HL,DONE
CALL OUTMSG
;
; PUT SYSTEM
;
PUTSYS:
CALL CRLF
LD HL,ASKPUT
CALL CRMSG
CALL GETCHAR
CP CR
JP Z,REBOOT
SUB 'A'
CP NDISKS
JP C,PUTC
; INVALID DRIVE NAME
CALL BADDISK
JP PUTSYS ; TO TRY AGAIN
;
PUTC: ; SET DISK FROM REGISTER C
ADD A,'A'
LD (PDISK),A ; MESSAGE SET
SUB 'A'
LD (ACTDSK),A ; SAVE ACTIVE DISK NO
; PUT SYSTEM
LD HL,PUTMSG
CALL CRMSG
CALL GETCHAR
CP CR
JP NZ,REBOOT
CALL CRLF
CALL WRDSK
JP NZ,PUTSYS
LD HL,DONE
CALL OUTMSG
JP PUTSYS ; FOR ANOTHER PUT OPERATION
;
REBOOT:
CALL CRLF
JP BOOT
;
ERRSEL:
LD HL,SELMSG
JP ERR
;
ERRSYS:
LD HL,SYSMSG
JP ERR
;
ERRIO:
LD HL,IOMSG
JP ERR
;
ERRSIG:
LD HL,SIGMSG
JP ERR
;
ERR:
CALL OUTMSG
OR A,0FFH
RET
;
BADDISK:;BAD DISK NAME
LD HL,QDISK
CALL CRMSG
RET
;
; DATA AREAS
; MESSAGES
;
SIGNON: DB 'ROMWBW SYSGEN VER '
DB VERS/10+'0','.',VERS MOD 10+'0'
DB 0
ASKGET: DB 'SOURCE DRIVE NAME (OR RETURN TO SKIP): ',0
GETMSG: DB 'SOURCE ON '
GDISK: DS 1 ; FILLED IN AT GET FUNCTION
DB ':, THEN TYPE RETURN',0
ASKPUT: DB 'DESTINATION DRIVE NAME (OR RETURN TO REBOOT): ',0
PUTMSG: DB 'DESTINATION ON '
PDISK: DS 1 ; FILLED IN AT PUT FUNCTION
DB ':, THEN TYPE RETURN',0
ERRMSG: DB 'PERMANENT ERROR, TYPE RETURN TO IGNORE',0
DONE: DB 'FUNCTION COMPLETE',0
QDISK: DB 'INVALID DRIVE NAME (USE A-P)',0
NOFILE: DB 'NO SOURCE FILE ON DISK',0
BADFILE:
DB 'SOURCE FILE INCOMPLETE',0
SELMSG: DB 'DISK SELECTION ERROR',0
SYSMSG: DB 'NON-SYSTEM DISK ERROR',0
IOMSG: DB 'FATAL DISK I/O ERROR',0
SIGMSG: DB 'INVALID SYSTEM IMAGE (BAD SIGNATURE)',0
;
; VARIABLES
;
CBFTBL DW 0 ; ADDRESS OF CBIOS FUNCTION TABLE
IMGSIZ DB 0 ; IMAGE SIZE (COUNT OF 128 BYTE RECORDS)
;
RWFUN DB 0 ; ACTIVE READ/WRITE FUNCTION
RECCNT DB 0 ; ACTIVE REMAINING RECORDS TO READ/WRITE
BUFPTR DW 0 ; ACTIVE POINTER INTO BUFFER
;
ACTDSK DB 0 ; ACTIVE DISK NO
ACTTRK DW 0 ; ACTIVE TRACK
ACTSEC DW 0 ; ACTIVE SECTOR
ACTSPT DW 0 ; ACTIVE SECTORS PER TRACK
ACTFNC DW 0 ; ACTIVE FUNCTION (READ OR WRITE)
DS STKSIZE*2
STACK:
;
END

567
Source/Apps/Test/2piotst/2piotst.mac

@ -0,0 +1,567 @@
; 24.9.2018 PMS (b1ackmai1er)
; Modified version for ECB-ZILOG PERIPHERALS BOARD - TEST 2 PIO's
; 01.11.2011 WKA
; Assembler M80
; ECB-4PIO
; Testprogramm f�r die I/O-Karte ECB-4PIO in Z80-Mnemonics
PAGE 72
.Z80
ASEG
ORG 100H
;
;CP/M-ADDRESSES
;* * * * * * *
;
BOOT EQU 0 ;WARMBOOT CP/M
BDOS EQU 5 ;ENTRY BDOS
NMI EQU 66H ;Error-ROUTINE
;
;CONSOLE-CODES
;* * * * * * *
;
EOT EQU 4 ;END OF TEXT
BS EQU 8 ;BACKSPACE
TAB EQU 9 ;TABULATOR
LF EQU 0AH ;LINE-FEED
CR EQU 0DH ;CARRIAGE-RETURN
FF EQU 0CH ;FORM-FEED
ESC EQU 1BH ;ESCAPE
CTRLC EQU 'C'-40H ;CONTROL-C
CTRLW EQU 'W'-40H ;CONTROL-W
CTRLX EQU 'X'-40H ;CONTROL-X
CTRLY EQU 'Y'-40H ;CONTROL-Y
CTRLZ EQU 'Z'-40H ;CONTROL-Z
;
BASE EQU 0B8H ; 4 DIL-SCHALTER
;
PIO0AD EQU BASE+0 ; PIO 0 A DATEN
PIO0AC EQU BASE+2 ; PIO 0 A CONTROL
PIO0BD EQU BASE+1 ; PIO 0 B DATEN
PIO0BC EQU BASE+3 ; PIO 0 B CONTROL
;
PIO1AD EQU BASE+4 ; PIO 1 A DATEN
PIO1AC EQU BASE+6 ; PIO 1 A CONTROL
PIO1BD EQU BASE+5 ; PIO 1 B DATEN
PIO1BC EQU BASE+7 ; PIO 1 B CONTROL
;
MAIN: LD DE,PIO_SRTMSG
CALL PSTRIN
;
LD DE,INI_MSG
CALL PSTRIN
CALL INIT
;
LD DE,PIO0ADW ;PIO0 A
CALL PSTRIN
LD A,55H
PUSH AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
POP AF
OUT (PIO0AD),A
IN A,(PIO0AD)
PUSH AF
;
LD DE,PIO0ADR
CALL PSTRIN
POP AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
;
LD DE,PIO0ADW
CALL PSTRIN
LD A,0AAH
PUSH AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
POP AF
OUT (PIO0AD),A
IN A,(PIO0AD)
PUSH AF
;
LD DE,PIO0ADR
CALL PSTRIN
POP AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
;
LD DE,PIO0BDW ;PIO0 B
CALL PSTRIN
LD A,55H
PUSH AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
POP AF
OUT (PIO0BD),A
IN A,(PIO0BD)
PUSH AF
;
LD DE,PIO0BDR
CALL PSTRIN
POP AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
;
LD DE,PIO0BDW
CALL PSTRIN
LD A,0AAH
PUSH AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
POP AF
OUT (PIO0BD),A
IN A,(PIO0BD)
PUSH AF
;
LD DE,PIO0BDR
CALL PSTRIN
POP AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
;
LD DE,PIO1ADW ;PIO1 A
CALL PSTRIN
LD A,55H
PUSH AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
POP AF
OUT (PIO1AD),A
IN A,(PIO1AD)
PUSH AF
;
LD DE,PIO1ADR
CALL PSTRIN
POP AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
;
LD DE,PIO1ADW
CALL PSTRIN
LD A,0AAH
PUSH AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
POP AF
OUT (PIO1AD),A
IN A,(PIO1AD)
PUSH AF
;
LD DE,PIO1ADR
CALL PSTRIN
POP AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
;
LD DE,PIO1BDW ;PIO1 B
CALL PSTRIN
LD A,55H
PUSH AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
POP AF
OUT (PIO1BD),A
IN A,(PIO1BD)
PUSH AF
;
LD DE,PIO1BDR
CALL PSTRIN
POP AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
;
LD DE,PIO1BDW
CALL PSTRIN
LD A,0AAH
PUSH AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
POP AF
OUT (PIO1BD),A
IN A,(PIO1BD)
PUSH AF
;
LD DE,PIO1BDR
CALL PSTRIN
POP AF
CALL OUTB
LD DE,LINE_E
CALL PSTRIN
;
LD DE,PIO_ENDMSG
CALL PSTRIN
JP BOOT
;
;==========================================================================
INIT: LD HL,PIO0T ; PIO0 INITITALISIEREN
CALL INITX
LD HL,PIO1T ; PIO1 INITITALISIEREN
CALL INITX
RET
;
INITX: LD A,(HL) ; BYTE-ANZAHL
OR A
RET Z
LD B,A ; Port-Adresse nach C
INC HL
LD C,(HL)
INC HL
OTIR
JR INITX
;
PIO0T: DEFB 05 ; 5 BYTE ZUM PIO 0 A CONTROL
DEFB PIO0AC
DEFB 00000011B ; DIS-INT
DEFB 01001111B ; BETR.ART BYTE EINGABE
DEFB 01001111B ; BETR.ART BYTE EINGABE
DEFB 11001111B ; BETR.ART BIT EIN/AUSG.
DEFB 00000000B ; ALLES AUSG.
DEFB 01 ; 1 BYTE ZUM PIO 0 A DATEN
DEFB PIO0AD
DEFB 00000000B ; DATEN "LOW"
;
DEFB 05 ; 5 BYTE ZUM PIO 0 B CONTROL
DEFB PIO0BC
DEFB 00000011B ; DIS-INT
DEFB 01001111B ; BETR.ART BYTE EINGABE
DEFB 01001111B ; BETR.ART BYTE EINGABE
DEFB 11001111B ; BETR.ART BIT EIN/AUSG.
DEFB 00000000B ; ALLES AUSG.
DEFB 01 ; 1 BYTE ZUM PIO 0 B DATEN
DEFB PIO0BD
DEFB 00000000B ; DATEN "LOW"
DEFB 0 ; ENDE PIO 0 B -TABELLE
;
PIO1T: DEFB 05 ; 5 BYTE ZUM PIO 1 A CONTROL
DEFB PIO1AC
DEFB 00000011B ; DIS-INT
DEFB 01001111B ; BETR.ART BYTE EINGABE
DEFB 01001111B ; BETR.ART BYTE EINGABE
DEFB 11001111B ; BETR.ART BIT EIN/AUSG.
DEFB 00000000B ; ALLES AUSG.
DEFB 01 ; 1 BYTE ZUM PIO 1 A DATEN
DEFB PIO1AD
DEFB 00000000B ; DATEN "LOW"
;
DEFB 05 ; 5 BYTE ZUM PIO 1 B CONTROL
DEFB PIO1BC
DEFB 00000011B ; DIS-INT
DEFB 01001111B ; BETR.ART BYTE EINGABE
DEFB 01001111B ; BETR.ART BYTE EINGABE
DEFB 11001111B ; BETR.ART BIT EIN/AUSG.
DEFB 00000000B ; ALLES AUSG.
DEFB 01 ; 1 BYTE ZUM PIO 1 B DATEN
DEFB PIO1BD
DEFB 00000000B ; DATEN "LOW"
DEFB 0 ; ENDE PIO 1 B -TABELLE
;
;==========================================================================
;
;Output on Screen
;****************
;
PRBS: LD E,BS
CALL PCHAR
RET
;
;Output CR+LF on Screen
;**********************
;
CRLF: LD E,CR
CALL PCHAR
LD E,LF
CALL PCHAR
RET
;
;Output ASCII-Character
;**********************
;
PRINP: PUSH AF
LD E,A
CALL PCHAR
POP AF
RET;
;
;CALL BDOS with Register Save
;****************************
;
INCHA: LD C,1 ;INPUT CHARACTER TO A
JR BDO
PCHAR: LD C,2 ;PRINT CHARACTER IN E
JR BDO
PSTRIN: LD C,9 ;PRINT STRING
JR BDO
INBUFF: LD C,10 ;READ CONSOLE-BUFFER
JR BDO
CSTS: LD C,11 ;CONSOLE-STATUS
JR BDO
OPEN: LD C,15 ;OPEN FILE
JR BDO
CLOSE: LD C,16 ;CLOSE FILE
JR BDO
DELETE: LD C,19 ;DELETE FILE
JR BDO
READS: LD C,20 ;READ SEEK
JR BDO
WRITES: LD C,21 ;WRITE SEEK
JR BDO
MAKE: LD C,22 ;MAKE FILE
JR BDO
SETDMA: LD C,26 ;SET DMA-ADDRESS
BDO: PUSH HL
PUSH DE
PUSH BC
PUSH IX
PUSH IY
CALL BDOS
POP IY
POP IX
POP BC
POP DE
POP HL
RET
;
;DIRECT CONSOLE INPUT
;********************
;
INDCON: CALL INDCOX
CP 0
JR Z,INDCON
RET
;
INDCOX: LD C,6 ;Code for Direct Console Input
LD E,0FFH ;Code for Input
PUSH HL
PUSH DE
PUSH BC
PUSH IX
PUSH IY
CALL BDOS
POP IY
POP IX
POP BC
POP DE
POP HL
RET
;
;
;Output WORD
;***********
;
;PARAMETER: Entry WORD IN HL
;*********
;
OUTW: LD A,H
CALL OUTB
LD A,L
CALL OUTB
RET
;
;Output BYTE
;***********
;
;PARAMETER: Entry BYTE IN A
;*********
;
OUTB: PUSH AF
RRCA
RRCA
RRCA
RRCA
AND 0FH
CALL HBTHE ;Change Half-BYTE
POP AF
AND 0FH
CALL HBTHE
RET
;
;Output HALF-BYTE
;****************
;
;PARAMETER: Entry Half-BYTE IN A (BIT 0 - 3)
;*********
;
HBTHE: CP 0AH
JR C,HBTHE1
ADD A,7 ;Character to Letter
HBTHE1: ADD A,30H
LD E,A
CALL PCHAR
RET
;
;Input ADDRESS
;*************
;
;PARAMETER: Exit with ADDRESS IN HL
;*********
;
INADR: LD HL,0
INADR1: CALL INCHAR ;Input TETRADE
LD D,A
CALL INBYT1 ;IN HEXA
RET C ;END OF Input
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
OR L
LD L,A
JR INADR1 ;New Key
;
;
;Input BYTE
;**********
;
;PARAMTER: Exit with BYTE IN A
;********
;
INBYT: CALL INADR
LD A,L
RET
;
;Input of one TETRADE to A (BIT 0-3)
;************************************
;
INBYT1: SUB '0'
RET C
CP 'G'-30H
JR NC,INBYT3 ;Error
CP ':'-30H
JR C,INBYT2
CP 'A'-30H
JR C,INBYT3 ;Error
SUB 7
INBYT2: OR A
RET
;
INBYT3: SCF
RET
;
;Input ASCII-Character to A
;**************************
;
INCON: CALL INDCON ;Input ASCII-Character to A
CP CTRLC ;TEST CONTROL-C
JP Z,QUIT
CP CTRLX ;TEST CONTROL-X
JR Z,INCHA1
CP CTRLW ;TEST CONTROL-W
JR Z,INCHA3
CP CTRLY ;TEST CONTROL-Y
JR Z,INCHA2
CP BS
RET Z
CP CR
RET Z
CP ' '
JR C,INCON
JR INCH1
;
INCHAR: CALL INCHA ;Input ASCII-Character to A
CP CTRLC ;TEST CONTROL-C
JR Z,QUIT
CP CTRLX ;TEST CONTROL-X
JR Z,INCHA1
CP CTRLW ;TEST CONTROL-W
JR Z,INCHA3
CP CTRLY ;TEST CONTROL-Y
JR Z,INCHA2
CP BS
RET Z
CP CR
RET Z
CP ' '
JR C,INCHAR ;Input invalied
;
INCH1: CP 'A'
RET C ;Character ok
;
RES 5,A ;lower case -> upper case
RET
INCHA1: POP HL
LD E,FF
CALL PCHAR ;Clear screen
JP GOON
INCHA2: POP HL
LD E,FF
CALL PCHAR ;Clear screen
JP GOON
INCHA3: LD E,FF
CALL PCHAR
RET
;
;ABBRUCH DER BEARBEITUNG
;***********************
;
COMPLT: LD DE,TCOMP
CALL PSTRIN
JP GOON
QUIT: CALL CRLF
LD DE,TQUIT
JR FINIS
INTTIM: POP DE ;STACK OK
; CALL DESAK
LD DE,TNMIAB
CALL PSTRIN
LD DE,MAIN ;NEW ADDRESS
PUSH DE
RETN
FINIS: CALL PSTRIN ;AT BDOS-ERROR
GOON:
JP BOOT
;
;
;TEXT-Messages
;*************
;
TCOMP: DEFB ESC,21,0,14H,ESC,23,0
DEFM 'Function complete !!$'
TQUIT: DEFB ESC,23,0,14H,7
DEFM 'End Run RAMFTEST$'
TNMIAB: DEFB ESC,23,0,14H
DEFM 'Time Out !!$'
;
;
INI_MSG:DEFM 'ECB-4PIO Init all PIO Bit-Mode ',CR,LF,'$'
PIO0ADW:DEFM 'ECB-4PIO Write to PIO0AD ','$'
PIO0ADR:DEFM 'ECB-4PIO Read from PIO0AD ','$'
PIO0BDW:DEFM 'ECB-4PIO Write to PIO0BD ','$'
PIO0BDR:DEFM 'ECB-4PIO Read from PIO0BD ','$'
PIO1ADW:DEFM 'ECB-4PIO Write to PIO1AD ','$'
PIO1ADR:DEFM 'ECB-4PIO Read from PIO1AD ','$'
PIO1BDW:DEFM 'ECB-4PIO Write to PIO1BD ','$'
PIO1BDR:DEFM 'ECB-4PIO Read from PIO1BD ','$'
PIO_SRTMSG:
DEFM 'ECB-ZILOG PERIPHERALS start test 1.0',CR,LF,'$'
PIO_ENDMSG:
DEFM 'ECB-ZILOG PERIPHERALS end test 1.0',CR,LF,'$'
LINE_E: DEFM 'H',CR,LF,'$'
;
IF1
.PRINTX 'Pass 1 complete'
ENDIF
;
IF2
.PRINTX 'Pass 2 complete'
.PRINTX 'Assembly complete'
ENDIF
;
END

13
Source/Apps/Test/2piotst/Build.cmd

@ -0,0 +1,13 @@
@echo off
setlocal
set TOOLS=..\..\..\..\Tools
set PATH=%TOOLS%\zxcc;%PATH%
set CPMDIR80=%TOOLS%/cpm/
zxcc M80 -=2piotst/l || exit /b
zxcc L80 -2piotst,2piotst.com/n/e || exit /b
copy /Y 2piotst.com ..\..\..\..\Binary\Apps\Test\ || exit /b

8
Source/Apps/Test/2piotst/Clean.cmd

@ -0,0 +1,8 @@
@echo off
setlocal
if exist *.com del *.com
if exist *.lst del *.lst
if exist *.bin del *.bin
if exist *.rel del *.rel
if exist *.prn del *.prn

8
Source/Apps/Test/2piotst/Makefile

@ -0,0 +1,8 @@
OBJECTS = 2piotst.com
DEST = ../../../../Binary/Apps/Test
TOOLS =../../../../Tools
OTHERS = *.rel
include $(TOOLS)/Makefile.inc
2piotst.com : 2piotst.rel

40
Source/Apps/Test/Build.cmd

@ -0,0 +1,40 @@
@echo off
setlocal
set TOOLS=../../../Tools
set APPBIN=..\..\Binary\Apps
set PATH=%TOOLS%\tasm32;%TOOLS%\zxcc;%PATH%
set TASMTABS=%TOOLS%\tasm32
set CPMDIR80=%TOOLS%/cpm/
pushd DMAmon && call Build || exit /b & popd
pushd tstdskng && call Build || exit /b & popd
pushd inttest && call Build || exit /b & popd
pushd ppidetst && call Build || exit /b & popd
pushd ramtest && call Build || exit /b & popd
pushd I2C && call Build || exit /b & popd
pushd rzsz && call Build || exit /b & popd
pushd vdctest && call Build || exit /b & popd
pushd kbdtest && call Build || exit /b & popd
pushd ps2info && call Build || exit /b & popd
pushd 2piotst && call Build || exit /b & popd
pushd piomon && call Build || exit /b & popd
pushd banktest && call Build || exit /b & popd
pushd portscan && call Build || exit /b & popd
goto :eof
:asm
echo.
echo Building %1...
tasm -t80 -g3 -fFF %1.asm %1.com %1.lst || exit /b
goto :eof
:asm180
echo.
echo Building %1...
tasm -t180 -g3 -fFF %1.asm %1.com %1.lst || exit /b
goto :eof

23
Source/Apps/Test/Clean.cmd

@ -0,0 +1,23 @@
@echo off
setlocal
if exist *.bin del *.bin
if exist *.com del *.com
if exist *.lst del *.lst
if exist *.hex del *.hex
if exist *.prn del *.prn
pushd DMAmon && call Clean || exit /b 1 & popd
pushd tstdskng && call Clean || exit /b 1 & popd
pushd inttest && call Clean || exit /b 1 & popd
pushd ppidetst && call Clean || exit /b 1 & popd
pushd ramtest && call Clean || exit /b 1 & popd
pushd I2C && call Clean || exit /b 1 & popd
pushd rzsz && call Clean || exit /b 1 & popd
pushd vdctest && call Clean || exit /b 1 & popd
pushd kbdtest && call Clean || exit /b 1 & popd
pushd ps2info && call Clean || exit /b 1 & popd
pushd 2piotst && call Clean || exit /b 1 & popd
pushd piomon && call Clean || exit /b 1 & popd
pushd banktest && call Clean || exit /b 1 & popd
pushd portscan && call Clean || exit /b 1 & popd

11
Source/Apps/Test/DMAmon/Build.cmd

@ -0,0 +1,11 @@
@echo off
setlocal
set TOOLS=../../../../Tools
set PATH=%TOOLS%\tasm32;%PATH%
set TASMTABS=%TOOLS%\tasm32
tasm -t180 -g3 -fFF dmamon.asm dmamon.com dmamon.lst || exit /b
copy /Y dmamon.com ..\..\..\..\Binary\Apps\Test\ || exit /b

6
Source/Apps/Test/DMAmon/Clean.cmd

@ -0,0 +1,6 @@
@echo off
setlocal
if exist *.com del *.com
if exist *.lst del *.lst
if exist *.bin del *.bin

7
Source/Apps/Test/DMAmon/Makefile

@ -0,0 +1,7 @@
OBJECTS = dmamon.com
DEST = ../../../../Binary/Apps/Test
TOOLS =../../../../Tools
USETASM=1
include $(TOOLS)/Makefile.inc

8
Source/Apps/Test/DMAmon/Readme.txt

@ -0,0 +1,8 @@
DMAmon is a program to verify operation of the Z80 MBC DMA board
Version 2 has been hacked to include testing for interrupts. This
requires running the application under RomWBW using IM2. There
is an equate in the source file to disable interrupt testing
if needed.
--WBW 10:36 AM 3/14/2022

1220
Source/Apps/Test/DMAmon/dmamon.asm

File diff suppressed because it is too large

969
Source/Apps/Test/DMAmon/util.asm

@ -0,0 +1,969 @@
;
;==================================================================================================
; UTILITY FUNCTIONS
;==================================================================================================
;
;
CHR_BEL .EQU 07H
CHR_CR .EQU 0DH
CHR_LF .EQU 0AH
CHR_BS .EQU 08H
CHR_ESC .EQU 1BH
;
;__________________________________________________________________________________________________
;
; UTILITY PROCS TO PRINT SINGLE CHARACTERS WITHOUT TRASHING ANY REGISTERS
;
PC_SPACE:
PUSH AF
LD A,' '
JR PC_PRTCHR
PC_PERIOD:
PUSH AF
LD A,'.'
JR PC_PRTCHR
PC_COLON:
PUSH AF
LD A,':'
JR PC_PRTCHR
PC_COMMA:
PUSH AF
LD A,','
JR PC_PRTCHR
PC_LBKT:
PUSH AF
LD A,'['
JR PC_PRTCHR
PC_RBKT:
PUSH AF
LD A,']'
JR PC_PRTCHR
PC_LT:
PUSH AF
LD A,'<'
JR PC_PRTCHR
PC_GT:
PUSH AF
LD A,'>'
JR PC_PRTCHR
PC_LPAREN:
PUSH AF
LD A,'('
JR PC_PRTCHR
PC_RPAREN:
PUSH AF
LD A,')'
JR PC_PRTCHR
PC_ASTERISK:
PUSH AF
LD A,'*'
JR PC_PRTCHR
PC_CR:
PUSH AF
LD A,CHR_CR
JR PC_PRTCHR
PC_LF:
PUSH AF
LD A,CHR_LF
JR PC_PRTCHR
PC_PRTCHR:
CALL COUT
POP AF
RET
NEWLINE2:
CALL NEWLINE
NEWLINE:
CALL PC_CR
CALL PC_LF
RET
;
; PRINT A CHARACTER REFERENCED BY POINTER AT TOP OF STACK
; USAGE:
; CALL PRTCH
; .DB 'X'
;
PRTCH:
EX (SP),HL
PUSH AF
LD A,(HL)
CALL COUT
POP AF
INC HL
EX (SP),HL
RET
;
; PRINT A STRING AT ADDRESS SPECIFIED IN HL
; STRING MUST BE TERMINATED BY '$'
; USAGE:
; LD HL,MYSTR
; CALL PRTSTR
; ...
; MYSTR: .DB "HELLO$"
;
PRTSTR:
LD A,(HL)
INC HL
CP '$'
RET Z
CALL COUT
JR PRTSTR
;
; PRINT A STRING DIRECT: REFERENCED BY POINTER AT TOP OF STACK
; STRING MUST BE TERMINATED BY '$'
; USAGE:
; CALL PRTSTRD
; .DB "HELLO$"
; ...
;
PRTSTRD:
EX (SP),HL
PUSH AF
CALL PRTSTR
POP AF
EX (SP),HL
RET
;
; PRINT A STRING INDIRECT: REFERENCED BY INDIRECT POINTER AT TOP OF STACK
; STRING MUST BE TERMINATED BY '$'
; USAGE:
; CALL PRTSTRI(MYSTRING)
; MYSTRING .DB "HELLO$"
;
PRTSTRI:
EX (SP),HL
PUSH AF
LD A,(HL)
INC HL
PUSH HL
LD H,(HL)
LD L,A
CALL PRTSTR
POP HL
INC HL
POP AF
EX (SP),HL
RET
;
; PRINT THE HEX BYTE VALUE IN A
;
PRTHEXBYTE:
PUSH AF
PUSH DE
CALL HEXASCII
LD A,D
CALL COUT
LD A,E
CALL COUT
POP DE
POP AF
RET
;
; PRINT THE HEX WORD VALUE IN BC
;
PRTHEXWORD:
PUSH AF
LD A,B
CALL PRTHEXBYTE
LD A,C
CALL PRTHEXBYTE
POP AF
RET
;
; PRINT THE HEX WORD VALUE IN HL
;
PRTHEXWORDHL:
PUSH AF
LD A,H
CALL PRTHEXBYTE
LD A,L
CALL PRTHEXBYTE
POP AF
RET
;
; PRINT THE HEX DWORD VALUE IN DE:HL
;
PRTHEX32:
PUSH BC
PUSH DE
POP BC
CALL PRTHEXWORD
PUSH HL
POP BC
CALL PRTHEXWORD
POP BC
RET
;
; CONVERT BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE
;
HEXASCII:
LD D,A
CALL HEXCONV
LD E,A
LD A,D
RLCA
RLCA
RLCA
RLCA
CALL HEXCONV
LD D,A
RET
;
; CONVERT LOW NIBBLE OF A TO ASCII HEX
;
HEXCONV:
AND 0FH ;LOW NIBBLE ONLY
ADD A,90H
DAA
ADC A,40H
DAA
RET
;
; PRINT A BYTE BUFFER IN HEX POINTED TO BY DE
; REGISTER A HAS SIZE OF BUFFER
;
PRTHEXBUF:
OR A
RET Z ; EMPTY BUFFER
;
LD B,A
PRTHEXBUF1:
CALL PC_SPACE
LD A,(DE)
CALL PRTHEXBYTE
INC DE
DJNZ PRTHEXBUF1
RET
;
; PRINT A BLOCK OF MEMORY NICELY FORMATTED
; DE=BUFFER ADDRESS
;
DUMP_BUFFER:
CALL NEWLINE
PUSH DE
POP HL
INC D
INC D
DB_BLKRD:
PUSH BC
PUSH HL
POP BC
CALL PRTHEXWORD ; PRINT START LOCATION
POP BC
CALL PC_SPACE ;
LD C,16 ; SET FOR 16 LOCS
PUSH HL ; SAVE STARTING HL
DB_NXTONE:
LD A,(HL) ; GET BYTE
CALL PRTHEXBYTE ; PRINT IT
CALL PC_SPACE ;
DB_UPDH:
INC HL ; POINT NEXT
DEC C ; DEC. LOC COUNT
JR NZ,DB_NXTONE ; IF LINE NOT DONE
; NOW PRINT 'DECODED' DATA TO RIGHT OF DUMP
DB_PCRLF:
CALL PC_SPACE ; SPACE IT
LD C,16 ; SET FOR 16 CHARS
POP HL ; GET BACK START
DB_PCRLF0:
LD A,(HL) ; GET BYTE
AND 060H ; SEE IF A 'DOT'
LD A,(HL) ; O.K. TO GET
JR NZ,DB_PDOT ;
DB_DOT:
LD A,2EH ; LOAD A DOT
DB_PDOT:
CALL COUT ; PRINT IT
INC HL ;
LD A,D ;
CP H ;
JR NZ,DB_UPDH1 ;
LD A,E ;
CP L ;
JP Z,DB_END ;
DB_UPDH1:
; IF BLOCK NOT DUMPED, DO NEXT CHARACTER OR LINE
DEC C ; DEC. CHAR COUNT
JR NZ,DB_PCRLF0 ; DO NEXT
DB_CONTD:
CALL NEWLINE ;
JP DB_BLKRD ;
DB_END:
RET
;
; PRINT THE nTH STRING IN A LIST OF STRINGS WHERE EACH IS TERMINATED BY $
; C REGISTER CONTAINS THE INDEX TO THE STRING TO BE DISPLAYED.
; A REGISTER CONTAINS A MASK TO BE APPLIED TO THE INDEX
; THE INDEX IS NORMALIZED TO A RANGE 0..N USING THE MASK AND THEN THE nTH
; STRING IS PRINTED IN A LIST DEFINED BY DE
;
; C = ATTRIBUTE
; A = MASK
; DE = STRING LIST
;
PRTIDXMSK:
PUSH BC
PRTIDXMSK0:
BIT 0,A
JR NZ,PRTIDXMSK1
SRL A
SRL C
JR PRTIDXMSK0
PRTIDXMSK1:
LD B,A
LD A,C
AND B
POP BC
;
; PRINT THE nTH STRING IN A LIST OF STRINGS WHERE EACH IS TERMINATED BY $
; A REGISTER DEFINES THE nTH STRING IN THE LIST TO PRINT AND DE POINTS
; TO THE START OF THE STRING LIST.
;
; SLOW BUT IMPROVES CODE SIZE, READABILITY AND ELIMINATES THE NEED HAVE
; LIST OF POINTERS OR A LIST OF CONDITIONAL CHECKS.
;
PRTIDXDEA:
PUSH BC
LD C,A ; INDEX COUNT
OR A
LD A,0
LD (PRTIDXCNT),A ; RESET CHARACTER COUNT
PRTIDXDEA1:
JR Z,PRTIDXDEA3
PRTIDXDEA2:
LD A,(DE) ; LOOP UNIT
INC DE ; WE REACH
CP '$' ; END OF STRING
JR NZ,PRTIDXDEA2
DEC C ; AT STRING END. SO GO
JR PRTIDXDEA1 ; CHECK FOR INDEX MATCH
PRTIDXDEA3:
POP BC
; CALL WRITESTR ; FALL THROUGH TO WRITESTR
; RET
;
; OUTPUT A '$' TERMINATED STRING AT DE
;
WRITESTR:
PUSH AF
WRITESTR1:
LD A,(DE)
CP '$' ; TEST FOR STRING TERMINATOR
JP Z,WRITESTR2
CALL COUT
LD A,(PRTIDXCNT)
INC A
LD (PRTIDXCNT),A
INC DE
JP WRITESTR1
WRITESTR2:
POP AF
RET
;
PRTIDXCNT:
.DB 0 ; CHARACTER COUNT
;
;
;
TSTPT:
PUSH DE
LD DE,STR_TSTPT
CALL WRITESTR
POP DE
JR REGDMP ; DUMP REGISTERS AND RETURN
;
;
;
REGDMP:
CALL XREGDMP
RET
;
XREGDMP:
EX (SP),HL ; RET ADR TO HL, SAVE HL ON TOS
LD (REGDMP_RET),HL ; SAVE RETURN ADDRESS
POP HL ; RESTORE HL AND BURN STACK ENTRY
EX (SP),HL ; PC TO HL, SAVE HL ON TOS
LD (REGDMP_PC),HL ; SAVE PC VALUE
EX (SP),HL ; BACK THE WAY IT WAS
LD (REGDMP_SP),SP ; SAVE STACK POINTER
;LD (RD_STKSAV),SP ; SAVE ORIGINAL STACK POINTER
;LD SP,RD_STACK ; SWITCH TO PRIVATE STACK
PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH AF
LD A,'@'
CALL COUT
POP AF
PUSH BC
LD BC,(REGDMP_PC)
CALL PRTHEXWORD ; PC
POP BC
CALL PC_LBKT
PUSH BC
PUSH AF
POP BC
CALL PRTHEXWORD ; AF
POP BC
CALL PC_COLON
CALL PRTHEXWORD ; BC
CALL PC_COLON
PUSH DE
POP BC
CALL PRTHEXWORD ; DE
CALL PC_COLON
PUSH HL
POP BC
CALL PRTHEXWORD ; HL
CALL PC_COLON
LD BC,(REGDMP_SP)
CALL PRTHEXWORD ; SP
CALL PC_COLON
PUSH IX
POP BC
CALL PRTHEXWORD ; IX
CALL PC_COLON
PUSH IY
POP BC
CALL PRTHEXWORD ; IY
CALL PC_RBKT
CALL PC_SPACE
POP HL
POP DE
POP BC
POP AF
;LD SP,(RD_STKSAV) ; BACK TO ORIGINAL STACK FRAME
JP $FFFF ; RETURN, $FFFF IS DYNAMICALLY UPDATED
REGDMP_RET .EQU $-2 ; RETURN ADDRESS GOES HERE
;
REGDMP_PC .DW 0
REGDMP_SP .DW 0
;
;RD_STKSAV .DW 0
; .FILL $FF,16*2 ; 16 LEVEL PRIVATE STACK
;RD_STACK .EQU $
;
;
;
;
;
STR_HALT .TEXT "\r\n\r\n*** System Halted ***$"
STR_TSTPT .TEXT "\r\n+++ TSTPT: $"
;STR_AF .DB " AF=$"
;STR_BC .DB " BC=$"
;STR_DE .DB " DE=$"
;STR_HL .DB " HL=$"
;STR_PC .DB " PC=$"
;STR_SP .DB " SP=$"
;
; INDIRECT JUMP TO ADDRESS IN HL
;
; MOSTLY USEFUL TO PERFORM AN INDIRECT CALL LIKE:
; LD HL,xxxx
; CALL JPHL
;
JPHL: JP (HL)
;
; ADD HL,A
;
; A REGISTER IS DESTROYED!
;
ADDHLA:
ADD A,L
LD L,A
RET NC
INC H
RET
;
;****************************
; A(BCD) => A(BIN)
; [00H..99H] -> [0..99]
;****************************
;
BCD2BYTE:
PUSH BC
LD C,A
AND 0F0H
SRL A
LD B,A
SRL A
SRL A
ADD A,B
LD B,A
LD A,C
AND 0FH
ADD A,B
POP BC
RET
;
;*****************************
; A(BIN) => A(BCD)
; [0..99] => [00H..99H]
;*****************************
;
BYTE2BCD:
PUSH BC
LD B,10
LD C,-1
BYTE2BCD1:
INC C
SUB B
JR NC,BYTE2BCD1
ADD A,B
LD B,A
LD A,C
ADD A,A
ADD A,A
ADD A,A
ADD A,A
OR B
POP BC
RET
#IFDEF USEDELAY
;
; DELAY 16US (CPU SPEED COMPENSATED) INCUDING CALL/RET INVOCATION
; REGISTER A AND FLAGS DESTROYED
; NO COMPENSATION FOR Z180 MEMORY WAIT STATES
; THERE IS AN OVERHEAD OF 3TS PER INVOCATION
; IMPACT OF OVERHEAD DIMINISHES AS CPU SPEED INCREASES
;
; CPU SCALER (CPUSCL) = (CPUHMZ - 2) FOR 16US + 3TS DELAY
; NOTE: CPUSCL MUST BE >= 1!
;
; EXAMPLE: 8MHZ CPU (DELAY GOAL IS 16US)
; LOOP = ((6 * 16) - 5) = 91TS
; TOTAL COST = (91 + 40) = 131TS
; ACTUAL DELAY = (131 / 8) = 16.375US
;
; --- TOTAL COST = (LOOP COST + 40) TS -----------------+
DELAY: ; 17TS (FROM INVOKING CALL) |
LD A,(CPUSCL) ; 13TS |
; |
DELAY1: ; |
; --- LOOP = ((CPUSCL * 16) - 5) TS ------------+ |
DEC A ; 4TS | |
#IF (BIOS == BIOS_WBW) ; | |
#IF (CPUFAM == CPU_Z180) ; | |
OR A ; +4TS FOR Z180 | |
#ENDIF ; | |
#ENDIF ; | |
JR NZ,DELAY1 ; 12TS (NZ) / 7TS (Z) | |
; ----------------------------------------------+ |
; |
RET ; 10TS (RETURN) |
;-------------------------------------------------------+
;
; DELAY 16US * DE (CPU SPEED COMPENSATED)
; REGISTER DE, A, AND FLAGS DESTROYED
; NO COMPENSATION FOR Z180 MEMORY WAIT STATES
; THERE IS A 27TS OVERHEAD FOR CALL/RET PER INVOCATION
; IMPACT OF OVERHEAD DIMINISHES AS DE AND/OR CPU SPEED INCREASES
;
; CPU SCALER (CPUSCL) = (CPUHMZ - 2) FOR 16US OUTER LOOP COST
; NOTE: CPUSCL MUST BE > 0!
;
; EXAMPLE: 8MHZ CPU, DE=6250 (DELAY GOAL IS .1 SEC OR 100,000US)
; INNER LOOP = ((16 * 6) - 5) = 91TS
; OUTER LOOP = ((91 + 37) * 6250) = 800,000TS
; ACTUAL DELAY = ((800,000 + 27) / 8) = 100,003US
;
; --- TOTAL COST = (OUTER LOOP + 27) TS ------------------------+
VDELAY: ; 17TS (FROM INVOKING CALL) |
; |
; --- OUTER LOOP = ((INNER LOOP + 37) * DE) TS ---------+ |
LD A,(CPUSCL) ; 13TS | |
; | |
VDELAY1: ; | |
; --- INNER LOOP = ((CPUSCL * 16) - 5) TS ------+ | |
#IF (BIOS == BIOS_WBW) ; | | |
#IF (CPUFAM == CPU_Z180) ; | | |
OR A ; +4TS FOR Z180 | | |
#ENDIF ; | | |
#ENDIF ; | | |
DEC A ; 4TS | | |
JR NZ,VDELAY1 ; 12TS (NZ) / 7TS (Z) | | |
; ----------------------------------------------+ | |
; | |
DEC DE ; 6TS | |
#IF (BIOS == BIOS_WBW) ; | | |
#IF (CPUFAM == CPU_Z180) ; | |
OR A ; +4TS FOR Z180 | |
#ENDIF ; | |
#ENDIF ; | |
LD A,D ; 4TS | |
OR E ; 4TS | |
JP NZ,VDELAY ; 10TS | |
;-------------------------------------------------------+ |
; |
RET ; 10TS (FINAL RETURN) |
;---------------------------------------------------------------+
;
; DELAY ABOUT 0.5 SECONDS
; 500000US / 16US = 31250
;
LDELAY:
PUSH AF
PUSH DE
LD DE,31250
CALL VDELAY
POP DE
POP AF
RET
;
; INITIALIZE DELAY SCALER BASED ON OPERATING CPU SPEED
; ENTER WITH A = CPU SPEED IN MHZ
;
DELAY_INIT:
CP 3 ; TEST FOR <= 2 (SPECIAL HANDLING)
JR C,DELAY_INIT1 ; IF <= 2, SPECIAL PROCESSING
SUB 2 ; ADJUST AS REQUIRED BY DELAY FUNCTIONS
JR DELAY_INIT2 ; AND CONTINUE
DELAY_INIT1:
LD A,1 ; USE THE MIN VALUE OF 1
DELAY_INIT2:
LD (CPUSCL),A ; UPDATE CPU SCALER VALUE
RET
#IF (CPUMHZ < 3)
CPUSCL .DB 1 ; CPU SCALER MUST BE > 0
#ELSE
CPUSCL .DB CPUMHZ - 2 ; OTHERWISE 2 LESS THAN PHI MHZ
#ENDIF
;
#ENDIF
;
; SHORT DELAY FUNCTIONS. NO CLOCK SPEED COMPENSATION, SO THEY
; WILL RUN LONGER ON SLOWER SYSTEMS. THE NUMBER INDICATES THE
; NUMBER OF CALL/RET INVOCATIONS. A SINGLE CALL/RET IS
; 27 T-STATES ON A Z80, 25 T-STATES ON A Z180
;
; ; Z80 Z180
; ; ---- ----
DLY64: CALL DLY32 ; 1728 1600
DLY32: CALL DLY16 ; 864 800
DLY16: CALL DLY8 ; 432 400
DLY8: CALL DLY4 ; 216 200
DLY4: CALL DLY2 ; 108 100
DLY2: CALL DLY1 ; 54 50
DLY1: RET ; 27 25
;
; MULTIPLY 8-BIT VALUES
; IN: MULTIPLY H BY E
; OUT: HL = RESULT, E = 0, B = 0
;
MULT8:
LD D,0
LD L,D
LD B,8
MULT8_LOOP:
ADD HL,HL
JR NC,MULT8_NOADD
ADD HL,DE
MULT8_NOADD:
DJNZ MULT8_LOOP
RET
;
; MULTIPLY A 16 BIT BY 8 BIT INTO 16 BIT
; IN: MULTIPLY DE BY A
; OUT: HL = RESULT, B=0, A, C, DE UNCHANGED
;
MULT8X16:
LD B,8
LD HL,0
MULT8X16_1:
ADD HL,HL
RLCA
JR NC,MULT8X16_2
ADD HL,DE
MULT8X16_2:
DJNZ MULT8X16_1
RET
;;
;; COMPUTE HL / DE
;; RESULT IN BC, REMAINDER IN HL, AND SET ZF DEPENDING ON REMAINDER
;; A, DE DESTROYED
;;
;DIV:
; XOR A
; LD BC,0
;DIV1:
; SBC HL,DE
; JR C,DIV2
; INC BC
; JR DIV1
;DIV2:
; XOR A
; ADC HL,DE ; USE ADC SO ZF IS SET
; RET
;===============================================================
;
; COMPUTE HL / DE = BC W/ REMAINDER IN HL & ZF
;
DIV16:
LD A,H ; HL -> AC
LD C,L ; ...
LD HL,0 ; INIT HL
LD B,16 ; INIT LOOP COUNT
DIV16A:
SCF
RL C
RLA
ADC HL,HL
SBC HL,DE
JR NC,DIV16B
ADD HL,DE
DEC C
DIV16B:
DJNZ DIV16A ; LOOP AS NEEDED
LD B,A ; AC -> BC
LD A,H ; SET ZF
OR L ; ... BASED ON REMAINDER
RET ; DONE
;
; INTEGER DIVIDE DE:HL BY C
; RESULT IN DE:HL, REMAINDER IN A
; CLOBBERS F, B
;
DIV32X8:
XOR A
LD B,32
DIV32X8A:
ADD HL,HL
RL E
RL D
RLA
CP C
JR C,DIV32X8B
SUB C
INC L
DIV32X8B:
DJNZ DIV32X8A
RET
;
; FILL MEMORY AT HL WITH VALUE A, LENGTH IN BC, ALL REGS USED
; LENGTH *MUST* BE GREATER THAN 1 FOR PROPER OPERATION!!!
;
FILL:
LD D,H ; SET DE TO HL
LD E,L ; SO DESTINATION EQUALS SOURCE
LD (HL),A ; FILL THE FIRST BYTE WITH DESIRED VALUE
INC DE ; INCREMENT DESTINATION
DEC BC ; DECREMENT THE COUNT
LDIR ; DO THE REST
RET ; RETURN
;
; SET A BIT IN BYTE ARRAY AT HL, INDEX IN A
;
BITSET:
CALL BITLOC ; LOCATE THE BIT
OR (HL) ; SET THE SPECIFIED BIT
LD (HL),A ; SAVE IT
RET ; RETURN
;
; CLEAR A BIT IN BYTE ARRAY AT HL, INDEX IN A
;
BITCLR:
CALL BITLOC ; LOCATE THE BIT
CPL ; INVERT ALL BITS
AND (HL) ; CLEAR SPECIFIED BIT
LD (HL),A ; SAVE IT
RET ; RETURN
;
; GET VALUE OF A BIT IN BYTE ARRAY AT HL, INDEX IN A
;
BITTST:
CALL BITLOC ; LOCATE THE BIT
AND (HL) ; SET Z FLAG BASED ON BIT
RET ; RETURN
;
; LOCATE A BIT IN BYTE ARRAY AT HL, INDEX IN A
; RETURN WITH HL POINTING TO BYTE AND A WITH MASK FOR SPECIFIC BIT
;
BITLOC:
PUSH AF ; SAVE BIT INDEX
SRL A ; DIVIDE BY 8 TO GET BYTE INDEX
SRL A ; "
SRL A ; "
LD C,A ; MOVE TO BC
LD B,0 ; "
ADD HL,BC ; HL NOW POINTS TO BYTE CONTAINING BIT
POP AF ; RECOVER A (INDEX)
AND $07 ; ISOLATE REMAINDER, Z SET IF ZERO
LD B,A ; SETUP SHIFT COUNTER
LD A,1 ; SETUP A WITH MASK
RET Z ; DONE IF ZERO
BITLOC1:
SLA A ; SHIFT
DJNZ BITLOC1 ; LOOP AS NEEDED
RET ; DONE
;
; PRINT VALUE OF A IN DECIMAL WITH LEADING ZERO SUPPRESSION
;
PRTDECB:
PUSH HL
PUSH AF
LD L,A
LD H,0
CALL PRTDEC
POP AF
POP HL
RET
;
; PRINT VALUE OF HL IN DECIMAL WITH LEADING ZERO SUPPRESSION
;
PRTDEC:
PUSH BC
PUSH DE
PUSH HL
LD E,'0'
LD BC,-10000
CALL PRTDEC1
LD BC,-1000
CALL PRTDEC1
LD BC,-100
CALL PRTDEC1
LD C,-10
CALL PRTDEC1
LD E,0
LD C,-1
CALL PRTDEC1
POP HL
POP DE
POP BC
RET
PRTDEC1:
LD A,'0' - 1
PRTDEC2:
INC A
ADD HL,BC
JR C,PRTDEC2
SBC HL,BC
CP E
JR Z,PRTDEC3
LD E,0
CALL COUT
PRTDEC3:
RET
;
; SHIFT HL:DE BY B BITS
;
SRL32:
; ROTATE RIGHT 32 BITS, HIGH ORDER BITS BECOME ZERO
SRL D
RR E
RR H
RR L
DJNZ SRL32
RET
;
SLA32:
; ROTATE LEFT 32 BITS, LOW ORDER BITS BECOME ZERO
SLA L
RL H
RL E
RL D
DJNZ SLA32
RET
;
; LOAD OR STORE DE:HL
;
LD32:
; LD DE:HL,(HL)
PUSH AF
LD E,(HL)
INC HL
LD D,(HL)
INC HL
LD A,(HL)
INC HL
LD H,(HL)
LD L,A
POP AF
EX DE,HL
RET
;
ST32:
; LD (BC),DE:HL
PUSH AF
LD A,L
LD (BC),A
INC BC
LD A,H
LD (BC),A
INC BC
LD A,E
LD (BC),A
INC BC
LD A,D
LD (BC),A
POP AF
RET
;
; INC/ADD/DEC/SUB 32 BIT VALUE IN DE:HL
; FOR ADD/SUB, OPERAND IS IN BC
;
INC32:
LD BC,1
ADD32:
ADD HL,BC
RET NC
INC DE
RET
;
DEC32:
LD BC,1
SUB32:
OR A
SBC HL,BC
RET NC
DEC DE
RET
;
; INC32 (HL)
; INCREMENT 32 BIT BINARY AT ADDRESS
;
INC32HL:
INC (HL)
RET NZ
INC HL
INC (HL)
RET NZ
INC HL
INC (HL)
RET NZ
INC HL
INC (HL)
RET

13
Source/Apps/Test/I2C/Build.cmd

@ -0,0 +1,13 @@
@echo off
setlocal
set TOOLS=../../../../Tools
set PATH=%TOOLS%\tasm32;%PATH%
set TASMTABS=%TOOLS%\tasm32
tasm -t180 -g3 -fFF i2cscan.asm i2cscan.com i2cscan.lst || exit /b
tasm -t180 -g3 -fFF rtcds7.asm rtcds7.com rtcds7.lst || exit /b
tasm -t180 -g3 -fFF i2clcd.asm i2clcd.com i2clcd.lst || exit /b
copy /Y i2c*.com ..\..\..\..\Binary\Apps\Test\ || exit /b
copy /Y rtcds7*.com ..\..\..\..\Binary\Apps\Test\ || exit /b

5
Source/Apps/Test/I2C/Clean.cmd

@ -0,0 +1,5 @@
@echo off
setlocal
if exist *.com del *.com
if exist *.lst del *.lst

8
Source/Apps/Test/I2C/Makefile

@ -0,0 +1,8 @@
OBJECTS = i2cscan.com rtcds7.com i2clcd.com
DEST = ../../../../Binary/Apps/Test/
TOOLS = ../../../../Tools
USETASM=1
TASMFLAGS=-dWBW
include $(TOOLS)/Makefile.inc

132
Source/Apps/Test/I2C/i2ccpm.inc

@ -0,0 +1,132 @@
;==================================================================================================
; GENERIC CP/M ROUTINES
;==================================================================================================
;
BDOS .EQU 5 ;ENTRY BDOS
BS .EQU 8 ;BACKSPACE
TAB .EQU 9 ;TABULATOR
LF .EQU 0AH ;LINE-FEED
CR .EQU 0DH ;CARRIAGE-RETURN
;
CLIARGS .EQU $81
RESTART .EQU $0000 ; CP/M restart vector
FCB .EQU $5C ; Location of default FCB
;
; OUTPUT TEXT AT HL
;
PRTSTR: LD A,(HL)
CP '$'
RET Z
CALL COUT
INC HL
JR PRTSTR
;
;Output WORD
;***********
;
;PARAMETER: Entry WORD IN HL
;*********
;
OUTW: LD A,H
CALL OUTB
LD A,L
CALL OUTB
RET
;
;Output BYTE
;***********
;
;PARAMETER: Entry BYTE IN A
;*********
;
OUTB: PUSH AF
RRCA
RRCA
RRCA
RRCA
AND 0FH
CALL HBTHE ;Change Half-BYTE
POP AF
AND 0FH
CALL HBTHE
RET
;
;Output HALF-BYTE
;****************
;
;PARAMETER: Entry Half-BYTE IN A (BIT 0 - 3)
;*********
;
HBTHE: CP 0AH
JR C,HBTHE1
ADD A,7 ;Character to Letter
HBTHE1: ADD A,30H
LD E,A
CALL PCHAR
RET
;
;
;Output on Screen
;****************
;
PRBS: LD E,BS
CALL PCHAR
RET
;
;Output CR+LF on Screen
;**********************
;
NEWLINE:
LD E,CR
CALL PCHAR
LD E,LF
CALL PCHAR
RET
;
;Output ASCII-Character
;**********************
;
COUT: PUSH AF
LD E,A
CALL PCHAR
POP AF
RET
;
;CALL BDOS with Register Save
;****************************
;
INCHA: LD C,1 ;INPUT CHARACTER TO A
JR BDO
PCHAR: LD C,2 ;PRINT CHARACTER IN E
JR BDO
PSTRIN: LD C,9 ;PRINT STRING
JR BDO
INBUFF: LD C,10 ;READ CONSOLE-BUFFER
JR BDO
CSTS: LD C,11 ;CONSOLE-STATUS
JR BDO
OPEN: LD C,15 ;OPEN FILE
JR BDO
CLOSE: LD C,16 ;CLOSE FILE
JR BDO
DELETE: LD C,19 ;DELETE FILE
JR BDO
READS: LD C,20 ;READ SEEK
JR BDO
WRITES: LD C,21 ;WRITE SEEK
JR BDO
MAKE: LD C,22 ;MAKE FILE
JR BDO
SETDMA: LD C,26 ;SET DMA-ADDRESS
BDO: PUSH HL
PUSH DE
PUSH BC
PUSH IX
PUSH IY
CALL BDOS
POP IY
POP IX
POP BC
POP DE
POP HL
RET

517
Source/Apps/Test/I2C/i2clcd.asm

@ -0,0 +1,517 @@
;==================================================================================================
; PCF8584 HD44780 I2C LCD UTILITY
;
; SOME GENERAL INFORMATION ON LCDS CAN BE SEEN HERE : FOCUSLCDS.COM/PRODUCT-CATEGORY/CHARACTER-LCD/
;
;==================================================================================================
;
.ECHO "i2clcd\n"
;
#INCLUDE "pcfi2c.inc"
;
; LCD COMMANDS
;
LCDFSET .EQU 00100000B ; 20H
LCD4BIT .EQU 00000000B ; 00H
LCD2LIN .EQU 00001000B ; 08H
LCDDON .EQU 00000100B ; 04H
LCDDMOV .EQU 00001000B ; 07H
LCDSGRA .EQU 01000000B ; 04H
LCDSDRA .EQU 10000000B ; 80H
LCDEMS .EQU 00000100B ; 04H
LCDELFT .EQU 00000010B ; 03H
;
LCDPINE .EQU 00000100B ; PIN 2
LCDPIND .EQU 00000001B ; PIN O
;
;
; STANDARD FORMATS - 8X1, 8X2, 16X1, 16X2, 16X4, 20X1, 20X2, 20X4, 24X2, 40X1, 40X2, 40X4
;
TIMEOUT .EQU 255
.ORG 100H
;INIT: CALL PCF_INIT
;
LD A,0
LD (DEBUGF),A
;
CALL LCDINIT ; SETUP THE LCD THROUGH THE PCF8574
LD HL,LCDDATA ; DISPLAY TEXT AT HL
PUSH HL
CALL LCDSTR
POP HL
CALL STOP ; CLOSE I2C CONNECTION
;
RET
;-----------------------------------------------------------------------------
;
LCDLITE .DB 00001000B
;
LCDINIT:
; CALL DEBUG
;
LD A,I2CLCDW ; SET SLAVE ADDRESS
OUT (REGS0),A
;
LD A,0C5H ; GENERATE START CONDITION
OUT (REGS1),A ; AND ISSUE THE SLAVE ADDRESS
CALL CHKPIN
;
; CALL DEBUG
;
LD HL,LCDINIT1
LD B,2
CALL WLN
;
CALL DELAY
;
LD HL,LCDINIT2
LD B,2
CALL WLN
;
CALL DELAY
;
; NOW WE ARE IN 4 BIT MODE
;
LD A,+(LCDFSET | LCD4BIT | LCD2LIN)
CALL LCDCMD
LD A,+(LCDDON | LCDDMOV)
CALL LCDCMD
LD A,+(LCDEMS | LCDELFT)
CALL LCDCMD
LD A,LCDSDRA
CALL LCDCMD
;
RET
;
;-----------------------------------------------------------------------------
;
WLN: LD A,(HL)
OUT (REGS0),A ; PUT DATA ON BUS
CALL CHKPIN
INC HL
DJNZ WLN
RET
;
;-----------------------------------------------------------------------------
; DISPLAY STRING AT HL, TERMINATED BY 0
;
LCDSTR: POP BC ; GET THE POINTER OF
POP HL ; THE TEXT TO DISPLAY
PUSH HL ; OFF THE STACK AND
PUSH BC ; PUT IT IN HL.
;
LCDST0: LD A,(HL) ; GET NEXT CHARACTER TO
OR A ; DISPLAY BUT RETURN
RET Z ; WHEN TERMINATOR REACHED
PUSH HL
;
CALL LCDATA ; OUTPUT TO LCD
POP HL
; RET C ; POINT TO NEXT
INC HL ; AND REPEAT
JR LCDST0
;
;-----------------------------------------------------------------------------
; SEND BYTE IN A TO LCD IN 4-BIT MODE
;
LCDATA: PUSH DE
LD D,A
LD A,(LCDLITE)
OR +(LCDPINE | LCDPIND)
JP LCDSND
LCDCMD: PUSH DE
LD D,A
LD A,(LCDLITE)
OR LCDPINE
LCDSND: LD E,A
LD A,D
PUSH BC
LD C,11110000B
AND C
OR E
LD (LCDBUF),A
AND ~LCDPINE
LD (LCDBUF+1),A
LD A,D
RLC A
RLC A
RLC A
RLC A
AND C
OR E
LD (LCDBUF+2),A
AND ~LCDPINE
LD (LCDBUF+3),A
;
LD HL,LCDBUF ; OUTPUT 1 BYTE WHICH
LD B,4 ; REQUIRES A FOUR
CALL WLN ; BYTE SEQUENCE
;
POP BC
POP DE
RET
;
LCDDATA:
.DB "TEST HOW BIG IS THIS LINE DOES IT WRAP",0
;
LCDINIT1:
.DB 00110100B
.DB 00011000B
;
LCDINIT2:
.DB 00100100B
.DB 00100000B
;
LCDBUF:
.DB 0, 0, 0, 0 ; BUFFER TO HOLD 4 BYTE SEQUENCE
; FLASH DEVICE READ
;
DEVMADR .EQU 0
READR: LD B,255
DLY1: DJNZ DLY1
;
LD A,D ; SET SLAVE ADDRESS
OUT (REGS0),A
;
LD A,0C5H ; GENERATE START CONDITION
OUT (REGS1),A ; AND ISSUE THE SLAVE ADDRESS
CALL CHKPIN
;
LD A,+(DEVMADR/256)
OUT (REGS0),A ; PUT ADDRESS MSB ON BUS
CALL CHKPIN
;
LD A,+(DEVMADR&$00FF)
OUT (REGS0),A ; PUT ADDRESS LSB ON BUS
CALL CHKPIN
;
LD A,045H ; START
OUT (REGS1),A
;
LD A,E ; ISSUE CONTROL BYTE + READ
OUT (REGS0),A
;
CALL READI2C ; DUMMY READ
JR NZ,ERREXT
;
READLP1:CALL READI2C
; JR Z,ERREXT
CP 1AH
PUSH AF
CALL COUT
POP AF
JR NZ,READLP1
;
LD A,PCF_ES0
OUT (REGS1),A
CALL CHKPIN
IN A,(REGS0)
CALL READI2C
CALL STOP
;
CALL NEWLINE
;
RET
;
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
RESET: LD A,0C2H ; STOP
OUT (REGS1),A
LD B,255
DLY2: DJNZ DLY2
LD A,0C1H
OUT (REGS1),A
RET
RDSTAT: LD BC,-1
STATLP: IN A,(REGS1)
AND 1
RET Z
LD A,B
OR C
DEC BC
JR NZ,STATLP
LD A,'T'
JP ERREXTT
;
ERREXT: LD A,'Q'
JR ERR
ERREXTT: POP HL
ERR: CALL COUT
CALL STOP
CALL RESET
RET
;
STOP: LD A,0C3H
OUT (REGS1),A
RET
;
DELAY: PUSH HL
LD HL,-1
DLOOP: LD A,H
OR L
DEC HL
JR NZ,DLOOP
POP HL
RET
;
CHKPIN: IN A,(REGS1) ; POLL FOR
BIT 7,A ; TRANSMISSION
JP NZ,CHKPIN ; TO FINISH
; IN A,(REGS1) ; CHECK FOR
BIT 3,A ; SLAVE
RET Z ; ACKNOWLEDGMENT
LD A,'A'
JP ERREXTT
;
; READ ONE BYTE FROM I2C
; RETURNS DATA IN A
; Z flag set is acknowledge received (correct operation)
;
READI2C:
IN A,(REGS1) ; READ S1 REGISTER
BIT 7,A ; CHECK PIN STATUS
JP NZ,READI2C
BIT 3,A ; CHECK LRB=0
RET NZ
IN A,(REGS0) ; GET DATA
RET
;
DEBUG: PUSH AF
PUSH DE
LD A,'['
CALL COUT
LD HL,DEBUGF
LD A,(HL)
INC (HL)
CALL HBTHE
LD A,']'
CALL COUT
POP DE
POP AF
RET
DEBUGF: .DB 00H
;
;-----------------------------------------------------------------------------
;
; LINUX DRIVER BASED CODE
;
; I2C_INB = IN A,(REGS0)
; I2C_OUTB = LD A,* | OUT (REGS0),A
; SET_PCF = LD A,* | OUT (REGS1),A
; GET_PCF = IN A,(REGS1)
;
;-----------------------------------------------------------------------------
I2C_START:
LD A,PCF_START_
OUT (REGS1),A
RET
;
;-----------------------------------------------------------------------------
I2C_REPSTART:
LD A,PCF_START_
OUT (REGS1),A
RET
;
;-----------------------------------------------------------------------------
I2C_STOP:
LD A,PCF_STOP_
OUT (REGS1),A
RET
;
;-----------------------------------------------------------------------------
HANDLE_LAB:
LABDLY .EQU 0F000H
LD A,PCF_PIN
OUT (REGS1),A
LD A,PCF_ES0
OUT (REGS1),A
;
LD HL,LABDLY
LABLP LD A,H
OR L
DEC HL
JR NZ,LABLP
;
IN A,(REGS1)
RET
;
;-----------------------------------------------------------------------------
WAIT_FOR_BB:
;
BBTIMO .EQU 255
;
LD HL,BBTIMO
BBNOTO IN A,(REGS1)
AND PCF_BB
RET Z
DEC HL
LD A,H
OR A
JR NZ,BBNOTO
CPL ; RET NZ IF TIMEOUT
BBNOTB RET ; RET Z IF BUS IS BUSY
;
;-----------------------------------------------------------------------------
WAIT_FOR_PIN:
;
; RETURN A=00/Z IF SUCCESSFULL
; RETURN A=FF/NZ IF TIMEOUT
; RETURN A=01/NZ IF LOST ARBITRATION
;
PINTIMO .EQU 16000
;
LD HL,PINTIMO
PINNOTO IN A,(REGS1)
LD (STATUS),A
LD B,A
AND PCF_PIN
RET Z
DEC HL
LD A,H
OR A
JR NZ,PINNOTO
CPL ; RET NZ IF TIMEOUT
PINNOTB RET ; RET Z IF BUS IS BUSY
;
LD B,A
AND PCF_LAB
CALL HANDLE_LAB
LD (STATUS),A
XOR A
INC A
RET
;
STATUS .DB 00H
;
;-----------------------------------------------------------------------------
PCF_INIT:
LD A,PCF_PIN ; S1=80H: S0 SELECTED, SERIAL
OUT (REGS1),A ; INTERFACE OFF
NOP
IN A,(REGS1) ; CHECK TO SEE S1 NOW USED AS R/W
AND 07FH ; CTRL. PCF8584 DOES THAT WHEN ESO
JR NZ,INIERR ; IS ZERO
;
LD A,PCF_OWN ; LOAD OWN ADDRESS IN S0,
OUT (REGS0),A ; EFFECTIVE ADDRESS IS (OWN <<1)
NOP
IN A,(REGS0) ; CHECK IT IS REALLY WRITTEN
CP PCF_OWN
JR NZ,SETERR
;
LD A,+(PCF_PIN | PCF_ES1) ; S1=0A0H
OUT (REGS1),A ; NEXT BYTE IN S2
NOP
IN A,(REGS1)
AND 07FH
CP PCF_ES1
JR NZ,REGERR
;
LD A,PCF_CLK ; LOAD CLOCK REGISTER S2
OUT (REGS0),A
NOP
IN A,(REGS0) ; CHECK IT'S REALLY WRITTEN, ONLY
AND 1FH ; THE LOWER 5 BITS MATTER
CP PCF_CLK
JR NZ,CLKERR
;
LD A,PCF_IDLE_
OUT (REGS1),A
NOP
IN A,(REGS1)
CP +(PCF_PIN | PCF_BB)
JR NZ,IDLERR
RET
;
;-----------------------------------------------------------------------------
PCF_SENDBYTES: ; HL POINTS TO DATA, BC = COUNT, A = 0 LAST A=1 NOT LAST
;
LD (LASTB),A
;
SB0: LD A,(HL)
OUT (REGS0),A
CALL WAIT_FOR_PIN
JR Z,SB1
CP 01H ; EXIT IF ARBITRATION ERROR
RET Z
CALL I2C_STOP ; MUST BE TIMEOUT
LD A,055H ; ERROR
RET
SB1: LD A,(STATUS)
AND PCF_LRB
JR NZ,SB2
LD A,055H
;
SB2: LD A,B
OR C
INC HL
JR NZ,SB0 ; CHECK IF FINISHED
;
SBGOOD: LD A,(LASTB)
OR A
JR NZ,DB3
CALL I2C_STOP
RET
DB3: CALL I2C_REPSTART
RET
;
LASTB .DB 00H
;
; I2C_INB = IN A,(REGS0)
; I2C_OUTB = LD A,* | OUT (REGS0),A
; SET_PCF = LD A,* | OUT (REGS1),A
; GET_PCF = IN A,(REGS1)
;
;-----------------------------------------------------------------------------
INIERR LD HL,NOPCF
CALL PRTSTR
RET
;
SETERR LD HL,WRTFAIL
CALL PRTSTR
RET
REGERR LD HL,REGFAIL
CALL PRTSTR
RET
;
CLKERR LD HL,CLKFAIL
CALL PRTSTR
RET
;
IDLERR LD HL,IDLFAIL
CALL PRTSTR
RET
;
NOPCF .DB "NO DEVICE FOUND",CR,LF,"$"
WRTFAIL .DB "SETTING DEVICE ID FAILED",CR,LF,"$"
REGFAIL .DB "CLOCK REGISTER SELECT ERROR",CR,LF,"$"
CLKFAIL .DB "CLOCK SET FAIL",CR,LF,"$"
IDLFAIL .DB "BUS IDLE FAILED",CR,LF,"$"
;
#INCLUDE "i2ccpm.inc"
;
BUFFER: .DS 256
;
.END

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save