mirror of https://github.com/wwarthen/RomWBW.git
committed by
GitHub
1657 changed files with 142750 additions and 168073 deletions
@ -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 |
||||
|
|||||
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
setlocal |
||||
|
|
||||
|
if exist *.com del *.com |
||||
@ -0,0 +1,7 @@ |
|||||
|
TOOLS = ../../../Tools |
||||
|
MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.com) |
||||
|
|
||||
|
include $(TOOLS)/Makefile.inc |
||||
|
|
||||
|
clean:: |
||||
|
@rm -f *.com |
||||
@ -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. |
||||
@ -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 |
||||
@ -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 |
||||
@ -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. |
||||
@ -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) |
|
||||
@ -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 |
||||
|
|||||
@ -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 |
|
||||
@ -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 |
||||
@ -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 |
||||
@ -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. |
||||
Binary file not shown.
@ -0,0 +1,6 @@ |
|||||
|
@echo off |
||||
|
setlocal |
||||
|
|
||||
|
pushd Source && call Build %* || exit /b & popd |
||||
|
|
||||
|
if "%*" == "" pause |
||||
@ -0,0 +1,5 @@ |
|||||
|
@echo off |
||||
|
setlocal |
||||
|
|
||||
|
pushd Binary && call Clean || exit /b 1 & popd |
||||
|
pushd Source && call Clean || exit /b 1 & popd |
||||
@ -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. |
|
||||
Binary file not shown.
Binary file not shown.
@ -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 |
||||
@ -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. |
|
||||
ôÙ |
|
||||
@ -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) |
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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 |
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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 |
||||
|
|||||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -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. |
|
||||
File diff suppressed because it is too large
@ -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 |
||||
@ -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 |
||||
@ -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 |
||||
|
|
||||
|
|
||||
@ -0,0 +1 @@ |
|||||
|
THE DEV DIRECTORY IS A SKELETON DIRECTORY TO AID SETTING UP A BUILD PROCESS FOR A NEW PROGRAM |
||||
@ -0,0 +1,32 @@ |
|||||
|
;=============================================================================== |
||||
|
; Dev - Developement Stub |
||||
|
;=============================================================================== |
||||
|
; |
||||
|
; AUTHOR: |
||||
|
; |
||||
|
; Usage: |
||||
|
; |
||||
|
;_______________________________________________________________________________ |
||||
|
; |
||||
|
; Change Log: |
||||
|
; |
||||
|
;_______________________________________________________________________________ |
||||
|
; |
||||
|
; ToDo: |
||||
|
; |
||||
|
;_______________________________________________________________________________ |
||||
|
; |
||||
|
;=============================================================================== |
||||
|
; Definitions |
||||
|
;=============================================================================== |
||||
|
; |
||||
|
; |
||||
|
;=============================================================================== |
||||
|
; Code Section |
||||
|
;=============================================================================== |
||||
|
; |
||||
|
; |
||||
|
.org $100 |
||||
|
ret |
||||
|
.end |
||||
|
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
@ -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) |
|
||||
File diff suppressed because it is too large
@ -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 |
||||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -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 |
|
||||
|
|
||||
@ -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 |
||||
@ -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 |
||||
@ -0,0 +1,6 @@ |
|||||
|
OBJECTS = survey.com |
||||
|
DEST = ../../../Binary/Apps |
||||
|
TOOLS = ../../../Tools |
||||
|
OTHERS = *.hex |
||||
|
|
||||
|
include $(TOOLS)/Makefile.inc |
||||
@ -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 |
||||
|
|
||||
@ -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 |
|
||||
@ -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 |
|
||||
@ -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 |
||||
|
|
||||
@ -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 |
||||
@ -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 |
||||
@ -0,0 +1,8 @@ |
|||||
|
OBJECTS = 2piotst.com |
||||
|
DEST = ../../../../Binary/Apps/Test |
||||
|
TOOLS =../../../../Tools |
||||
|
OTHERS = *.rel |
||||
|
|
||||
|
include $(TOOLS)/Makefile.inc |
||||
|
|
||||
|
2piotst.com : 2piotst.rel |
||||
@ -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 |
||||
@ -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 |
||||
@ -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 |
||||
|
|
||||
@ -0,0 +1,6 @@ |
|||||
|
@echo off |
||||
|
setlocal |
||||
|
|
||||
|
if exist *.com del *.com |
||||
|
if exist *.lst del *.lst |
||||
|
if exist *.bin del *.bin |
||||
@ -0,0 +1,7 @@ |
|||||
|
OBJECTS = dmamon.com |
||||
|
DEST = ../../../../Binary/Apps/Test |
||||
|
TOOLS =../../../../Tools |
||||
|
|
||||
|
USETASM=1 |
||||
|
|
||||
|
include $(TOOLS)/Makefile.inc |
||||
@ -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 |
||||
File diff suppressed because it is too large
@ -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 |
||||
|
|
||||
@ -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 |
||||
@ -0,0 +1,5 @@ |
|||||
|
@echo off |
||||
|
setlocal |
||||
|
|
||||
|
if exist *.com del *.com |
||||
|
if exist *.lst del *.lst |
||||
@ -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 |
||||
@ -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 |
||||
@ -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…
Reference in new issue