diff --git a/.gitignore b/.gitignore index 4782ed5c..e9b8986e 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,9 @@ Source/Images/blankhd Source/Prop/Spin/ParPortProp.list Source/Prop/Spin/PropIO.list Source/Prop/Spin/PropIO2.list +Source/Prop/ParPortProp.list +Source/Prop/PropIO.list +Source/Prop/PropIO2.list Source/ZPM3/bnkbios3.spr Source/ZPM3/gencpm.com Source/ZPM3/gencpm.com @@ -79,6 +82,7 @@ Tools/unix/zx/zx !Source/BPBIOS/Z34RCP11/cledsave.com !Source/Fonts !Source/Images/**/*.[Cc][Oo][Mm] +!Source/Images/hdnew_prefix.bin !Source/RomDsk/**/*.[Cc][Oo][Mm] !Source/UBIOS/FSFAT.BIN !Source/UBIOS/UNA-BIOS.BIN @@ -86,6 +90,7 @@ Tools/unix/zx/zx !Source/ZCPR-DJ/*.[Cc][Oo][Mm] !Source/ZPM3/*.[Cc][Oo][Mm] !Source/ZSDOS/*.[Cc][Oo][Mm] +!Source/ZRC/*.bin !Tools/cpm/bin !Tools/unix/zx !Tools/zx @@ -94,3 +99,6 @@ Source/ZPM3/gencpm.com Source/ZPM3/startzpm.com Source/ZPM3/zccp.com Source/ZPM3/zpmldr.com +Source/ZPM3/genbnk.dat + +Source/ZSDOS/zsdos.err \ No newline at end of file diff --git a/Binary/Apps/Makefile b/Binary/Apps/Makefile index cfa80100..7e63d751 100644 --- a/Binary/Apps/Makefile +++ b/Binary/Apps/Makefile @@ -7,4 +7,4 @@ all:: mkdir -p Tunes clobber:: - rm -f *.bin *.com *.img *.rom *.pdf *.log *.eeprom *.COM *.BIN Tunes/*.mym Tunes/*.pt? + @rm -f *.bin *.com *.img *.rom *.pdf *.log *.eeprom *.COM *.BIN Tunes/*.mym Tunes/*.pt? diff --git a/Binary/Apps/ReadMe.txt b/Binary/Apps/ReadMe.txt index 6fb4ccf8..1c8781b5 100644 --- a/Binary/Apps/ReadMe.txt +++ b/Binary/Apps/ReadMe.txt @@ -11,4 +11,11 @@ are specific to RomWBW. The source for these applications is found in the Source\Apps directory of the distribution. The Tunes subdirectory contains some sample ProTracker and MYM sound -files that can be played by the TUNE application. \ No newline at end of file +files that can be played by the TUNE application. + +All of these files are already included in the pre-built boot disk +images. They are also included on the ROM disk except for +FAT.COM, TUNE.COM, and the sample tune files in the Tunes directory. + +If you upgrade your ROM to a new version, you should also copy +these files over to any hard disk images you are using. \ No newline at end of file diff --git a/Binary/CPM3/Clean.cmd b/Binary/CPM3/Clean.cmd new file mode 100644 index 00000000..c909fdae --- /dev/null +++ b/Binary/CPM3/Clean.cmd @@ -0,0 +1,11 @@ +@echo off +setlocal + +if exist *.spr del *.spr +if exist *.com del *.com +if exist *.sys del *.sys +if exist *.pat del *.pat +if exist *.dat del *.dat +if exist *.1st del *.1st +if exist *.spr del *.spr +if exist *.pat del *.pat diff --git a/Binary/CPM3/Makefile b/Binary/CPM3/Makefile new file mode 100644 index 00000000..2105f8de --- /dev/null +++ b/Binary/CPM3/Makefile @@ -0,0 +1,7 @@ +TOOLS = ../../Tools +MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.spr) + +include $(TOOLS)/Makefile.inc + +clobber:: + @rm -f *.spr diff --git a/Binary/CPM3/ReadMe.txt b/Binary/CPM3/ReadMe.txt new file mode 100644 index 00000000..18f1ecb3 --- /dev/null +++ b/Binary/CPM3/ReadMe.txt @@ -0,0 +1,17 @@ +*********************************************************************** +*** *** +*** R o m W B W *** +*** *** +*** Z80/Z180 System Software *** +*** *** +*********************************************************************** + +This directory contains the CP/M 3 system files for the RomWBW CP/M 3 +adaptation. All of these files are already included on the CP/M 3 +boot disk images. However if you are creating a CP/M 3 boot disk +manually, you should copy all of these files to the boot disk. + +These files should also be copied to any CP/M 3 boot disks on your +system when you upgrade your ROM firmware. Some of these files +*must* match the version of the RomWBW firmware you are using for +proper operation of your system. \ No newline at end of file diff --git a/Binary/Clean.cmd b/Binary/Clean.cmd index b0b248d8..c00ca43e 100644 --- a/Binary/Clean.cmd +++ b/Binary/Clean.cmd @@ -2,11 +2,14 @@ setlocal if exist *.bin del *.bin +if exist *.dat del *.dat if exist *.com del *.com if exist *.img del *.img if exist *.rom del *.rom +if exist *.upd del *.upd if exist *.pdf del *.pdf -if exist *.log del *.log if exist *.eeprom del *.eeprom setlocal & cd Apps && call Clean || exit /b 1 & endlocal +setlocal & cd CPM3 && call Clean || exit /b 1 & endlocal +setlocal & cd ZPM3 && call Clean || exit /b 1 & endlocal diff --git a/Binary/DiskList.txt b/Binary/DiskList.txt index 8ecedd63..7701d6ed 100644 --- a/Binary/DiskList.txt +++ b/Binary/DiskList.txt @@ -17,6 +17,12 @@ a floppy or hard/CF/SD disk. You can use your modern computer media. The disk media will then be ready to use in your RomWBW System. +WARNING: The hdnew_*.img disk images are part of a new disk +format that is a work in progress. Do not use these disk +images without knowing exactly what you are doing! The +hd_*.img disk images continue to be the images you should +be using under normal circumstances. + 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 diff --git a/Binary/Makefile b/Binary/Makefile index c856d1b8..4b2e6294 100644 --- a/Binary/Makefile +++ b/Binary/Makefile @@ -1,8 +1,8 @@ TOOLS = ../Tools MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.img *.rom *.com *.eeprom) -SUBDIRS = Apps +SUBDIRS = Apps CPM3 ZPM3 include $(TOOLS)/Makefile.inc clobber:: - rm -f *.bin *.com *.img *.rom *.pdf *.log *.eeprom + @rm -f *.bin *.com *.img *.rom *.pdf *.log *.eeprom *.dat diff --git a/Binary/ReadMe.txt b/Binary/ReadMe.txt index 70156630..6118199f 100644 --- a/Binary/ReadMe.txt +++ b/Binary/ReadMe.txt @@ -42,6 +42,15 @@ MK4_custom.rom will be added to this directory. Documentation of the pre-built ROM Images is contained in the RomList.txt file in this directory. +ROM Firmware Update Images (_.upd) +------------------------------------- + +The files with a ".upd" extension are binary images identical to the +.rom files, but they only have the first 128K bytes. The first 128K +is the system image without the ROM disk contents. These files can be +used to update the system image without modifying the ROM disk +contents. Refer to the Getting Started document for more information. + ROM Executable Images (_.com) --------------------------------------- @@ -92,6 +101,12 @@ intended to be copied to the start of any type of hard disk media (typically a CF Card or SD Card). The resulting media will be usable on any RomWBW-based system that accepts the corresponding media type. +WARNING: The hdnew_*.img disk images are part of a new disk +format that is a work in progress. Do not use these disk +images without knowing exactly what you are doing! The +hd_*.img disk images continue to be the images you should +be using under normal circumstances. + Documentation of the pre-built disk images is contained in the DiskList.txt file in this directory. diff --git a/Binary/RomList.txt b/Binary/RomList.txt index 128e400e..02ca2f53 100644 --- a/Binary/RomList.txt +++ b/Binary/RomList.txt @@ -34,7 +34,7 @@ image to use for each platform: 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 + SC-series SC126, SC130, SC131 Easy Z80 EZZ180_std.rom Dyno DYNO_std.rom @@ -52,11 +52,6 @@ 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 @@ -66,10 +61,10 @@ All of the standard ROM Images are configured for: * 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. +automatically assigned at least 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 ------------------------ @@ -153,36 +148,35 @@ MK4 (MK4_std.rom): 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. + - Auto detects Serial I/O Module (ACIA), Dual Serial + Module (SIO/2), and EP Dual UART. - 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 + order of priority is UART, SIO, then ACIA. + - Baud rate is determined by hardware, but normally 115200. + - Auto support for RC2014 Compact Flash Module + - Auto 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 + - Support for J.B. Lang TMS9918 video card may be enabled in config + - Support for PropIO V2 may be enabled in config (PRPENABLE). If + enabled, will auto-detect and install associated + video, keyboard and SD Card support if present. RCZ80 w/ KIO (RCZ80_kio.rom): - - Assumes CPU oscillator of 7.3728 MHz - - Requires 512K RAM/ROM module + - Same as RCZ80_std - 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 + - SIO ports provided by KIO 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 + - Auto support for RC2014 Compact Flash Module + - Auto 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 + - Support for J.B. Lang TMS9918 video card 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 @@ -190,25 +184,67 @@ RCZ180 (RCZ180_nat.rom & RCZ180_ext.rom): addressing of memory, such as the SC119 - RCZ180_ext.rom uses external bank management to access memory, such as the 512K RAM/ROM module. + - Support for PropIO V2 may be enabled in config (PRPENABLE). If + enabled, will auto-detect and install associated + video, keyboard and SD Card support if present. -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 +RCZ280 (RCZ280_ext.rom): + - Assumes CPU oscillator of 24 MHz + - Bus clock will be 6 MHz, so does not match RC2014 standard!!! + - Requires 512K RAM/ROM module + - Auto detects Serial I/O Module (ACIA), Dual Serial + Module (SIO/2), and EP Dual UART. + - Console on whichever serial module is installed, + order of priority is UART, SIO, then ACIA. + - Baud rate is determined by hardware, but normally 115200. + - Auto support for RC2014 Compact Flash Module + - Auto 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 + - Support for J.B. Lang TMS9918 video card may be enabled in config + - Support for PropIO V2 may be enabled in config (PRPENABLE). If + enabled, will auto-detect and install associated + video, keyboard and SD Card support if present. + +RCZ280 (RCZ280_nat.rom): + - Assumes CPU oscillator of 24 MHz + - Bus clock will be 6 MHz, so does not match RC2014 standard!!! + - Requires native RAM/ROM module (linear memory) + - Interrupt Mode 3 only (no ACIA support possible) + - Auto detects Dual Serial Module (SIO/2), and EP Dual UART. + - Console on whichever serial module is installed, + order of priority is UART, then SIO. + - Baud rate is determined by hardware, but normally 115200. + - Auto support for RC2014 Compact Flash Module + - Auto 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 + - Support for J.B. Lang TMS9918 video card may be enabled in config + - Support for PropIO V2 may be enabled in config (PRPENABLE). If + enabled, will auto-detect and install associated + video, keyboard and SD Card support if present. + +SCZ180 (SCZ180_126.rom, SCZ180_130.rom, SCZ180_131.rom, SCZ140.rom): + - Same as RCZ180 + - Adds auto support for SPI SD Card - The 3 different variants of SCZ180 are provided to match the - 3 corresponding systems (SC126, SC130, and SC131) designed by - Stephen Cousins. + 3 corresponding systems (SC126, SC130, SC131, and SC140) + designed by Stephen Cousins. + - Support for PropIO V2 may be enabled in config (PRPENABLE). If + enabled, will auto-detect and install associated + video, keyboard and SD Card support if present. 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 + - Auto support for RC2014 Compact Flash Module + - Auto support for RC2014 PPIDE Module + - Support for PropIO V2 may be enabled in config (PRPENABLE). If + enabled, will auto-detect and install associated + video, keyboard and SD Card support if present. DYNO (DYNO_std.rom): - Assumes CPU oscillator of 18.432 MHz diff --git a/Binary/ZPM3/Clean.cmd b/Binary/ZPM3/Clean.cmd new file mode 100644 index 00000000..116507c8 --- /dev/null +++ b/Binary/ZPM3/Clean.cmd @@ -0,0 +1,10 @@ +@echo off +setlocal + +if exist *.spr del *.spr +if exist *.com del *.com +if exist *.sys del *.sys +if exist *.pat del *.pat +if exist *.dat del *.dat +if exist *.zpm del *.zpm +if exist *.spr del *.spr diff --git a/Binary/ZPM3/Makefile b/Binary/ZPM3/Makefile new file mode 100644 index 00000000..2105f8de --- /dev/null +++ b/Binary/ZPM3/Makefile @@ -0,0 +1,7 @@ +TOOLS = ../../Tools +MOREDIFF := $(shell $(TOOLS)/unix/casefn.sh *.spr) + +include $(TOOLS)/Makefile.inc + +clobber:: + @rm -f *.spr diff --git a/Binary/ZPM3/ReadMe.txt b/Binary/ZPM3/ReadMe.txt new file mode 100644 index 00000000..dcdef396 --- /dev/null +++ b/Binary/ZPM3/ReadMe.txt @@ -0,0 +1,17 @@ +*********************************************************************** +*** *** +*** R o m W B W *** +*** *** +*** Z80/Z180 System Software *** +*** *** +*********************************************************************** + +This directory contains the ZPM3 system files for the RomWBW ZPM3 +adaptation. All of these files are already included on the ZPM3 +boot disk images. However if you are creating a CP/M 3 boot disk +manually, you should copy all of these files to the boot disk. + +These files should also be copied to any ZPM3 boot disks on your +system when you upgrade your ROM firmware. Some of these files +*must* match the version of the RomWBW firmware you are using for +proper operation of your system. \ No newline at end of file diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index 8d28bd22..bab6a99f 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -1,3 +1,22 @@ +Version 3.1.1 +------------- +- WBW: Version bumped due to pervasive changes +- WBW: Preliminary hard disk partition support (backward compatible) +- WBW: Change Propeller VGA signal timings to 60Hz refresh +- WBW: Enhanced SYSTEM RESET function to allow a warm start back to boot loader +- C?O: Add DUART driver +- WBW: Early Z280 support (requires 512K RAM/ROM board) +- HCS: ZRC memory manager support +- S?K: Support for Tiny Z80 by Sergey +- E?B: Support for v6 YM/AY sound card +- C?M: Support for RC2014 bus PropIO V2 +- W?S: Updated FLASH software to v1.3.4 +- PMS: Preliminary support for writing to FLASH ROMs +- PMS: Creation of process to update ROM system area w/o updating ROM disk contents +- PMS: Added "updater.asm" which allows uploading and updating ROM in one step +- WBW: Support for Z280 w/ native memory and interrupt mode 3 +- WBW: Support for Z280 UART (interrupt driven only in interrupt mode 3) + Version 3.1 ----------- - WBW: Refactored ROM Loader @@ -6,6 +25,18 @@ Version 3.1 - WBW: Added support dual 16C550 UART on RC2014 platform - WBW: Made .com images smaller (contain only Z-System now) - WBW: Support automatic clock hardware detection and fallback +- WBW: Support use of CTC for SIO baud rate divisors +- WBW: Updated IDE and PPIDE drivers to improve old CF Card compatibility +- WBW: Support TIMER mode in CTC driver +- DEN: Added sound driver support +- DEN: Added SN76489 sound chip driver +- M?O: RomWBW Disk Catalog document +- DEN: Updated TMS to optionally trigger SYSTIMER interrupt (TMSTIMENABLE) +- J?M: Updated KERMIT applications with VT100 terminal support +- A?C: Added support for EPFDC +- PMS: Added AY driver with new sound API support +- DEN: Allow immediate autoboot startup +- DEN: Support for floppy device count parameter Version 3.0.1 ------------- @@ -99,7 +130,7 @@ Version 2.9.1 - PMS: Added Forth, Nascom BASIC, and Tasty BASIC to ROM - PMS: Refactored ROM Loader to support more ROM images, now table driven - WBW: Refactored DSKY code -- SK: Initial support for Easy Z80 +- S?K: Initial support for Easy Z80 - PMS: Enhance VDU driver to support alternative screen dimensions - WBW: DDT and DDTZ modified to use RST 30 instead of RST 38 to avoid conflicts with IM 1 interrupts - WBW: Added timer interrupt support for CTC under Zeta 2 and Easy Z80 @@ -277,7 +308,7 @@ Version 2.0 - DWG: Entire new suite of Apps written in Aztec C - DWG: BANKER.COM - displays bank identification and version information - DWG: CPMNAME.COM - displays CBIOS header data and SYSCFG data, names and vaues -- DWG: CHARS.COM - displays ascii map as reference +- DWG: CHARS.COM - displays ascii map as reference - DWG: CLS.COM - clears screen - DWG: LABEL.COM - displays and changes drive labels for drives with reserved tracks - DWG: MAP.COM - like old map command, displays drives and logical unit labels and changes LU values @@ -309,7 +340,7 @@ Version 1.5.1 - WBW: Added ZSDOS clock drivers (see Support\Clock) - WBW: Overhaul of ZSystem ROM Disk (see Doc\ZSystem.txt) - WBW: Update PropIO ANSI emulation for compatiblity with ASSIGN -- DWG: Added version tags to all applications, and IDENT program to +- DWG: Added version tags to all applications, and IDENT program to check version of utilities. - DWG: Added MULTIFMT program which prepares new media for use by initializing the metadata and clearing the directory sectors of @@ -319,8 +350,8 @@ Version 1.5.1 - DWG: ANALYSE and HELLO programs removed from ROM due space concerns - DWG: Additional macro librarties added supporting program identification (IDENTITY.LIB/ASM) and access to drive metadata (METADATA.LIB/ASM), - and realtime selection of logical units from within new application - programs (LOGICALS.LIB/ASM). + and realtime selection of logical units from within new application + programs (LOGICALS.LIB/ASM). - DWG: Added TERM_VT52 for VDU compatbility, all apps now compliant - DGG: Contributed Linux build (see Doc\BuildLinux.txt) @@ -348,7 +379,7 @@ Version 1.4 - DWG: Add various .SUB files used for application maintenance - DWG: Enhanced utility building .SUB files to only contain libs utilitized - DWG: Add BUILD.SUB to build all applications and DEVFILES.LBR -- DWG: Add/update RMAC macro libraries used in Apps - +- DWG: Add/update RMAC macro libraries used in Apps - - DWG: BIOSHDR, STDLIB, STRCPY, STRLEN, CPMBIOS, CPMBDOS, TERMINAL, HARDWARE, - DWG: CPMAPPL, GLOBALS, ATOI, LUBIND, APPLVERS, MEMORY(memcpy,memset), PORTAB - DWG: Add/Repair BIOS support for Boot Drive login during CP/M Coldstart @@ -367,7 +398,7 @@ Version 1.4 - DWG: Add LABEL utility to insert label into drive/slice metadata - DWG: Add 16 char label field to metadata - DWG: ASSIGN utility displays and manipulates DPH/DPB & logical unit parameters -- DWG/WBW: Collaborated on design of Logical Unit DPH enhancemnt +- DWG/WBW: Collaborated on design of Logical Unit DPH enhancemnt - WBW: Proposed MAP utility functionality - WBW: Implement slice selection API for DSK devices - WBW: Record boot drive in config memory at load time diff --git a/Doc/Contrib/Flash4.txt b/Doc/Contrib/Flash4.txt index 327f8c84..cac02ab9 100644 --- a/Doc/Contrib/Flash4.txt +++ b/Doc/Contrib/Flash4.txt @@ -1,186 +1,199 @@ - - FLASH4 (c) 2014 William R Sowerbutts - 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. + + FLASH4 (c) 2014-2020 William R Sowerbutts + http://sowerbutts.com/8bit/ + += Supported machines = + +FLASH4 has been tested and confirmed working on: + * N8VEM SBCv2 + * N8VEM SBCv2 MegaFlash + * N8VEM N8-2312 + * N8VEM Mark IV SBC + * DX-Designs P112 + * ZETA SBC v1 + * ZETA SBC v2 + * RC2014 with 512KB ROM 512KB RAM module + +It should work on many other machines that run RomWBW or UNA BIOS. If you test +it on another machine please let me know the outcome. + + += 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 and machines. Ideally I would +like to support all Z80/Z180 machines. If FLASH4 does not support your machine +please let me know and I will try to add support. + +When writing to the Flash ROM, 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 version 1.3 introduces support for programming multiple flash chips. +Some machines use multiple flash chips for larger ROM capacity, for example the +"Megaflash" version of the Retrobrew Computers SBC-V2 contains two 512KB flash +ROMs for a total of 1MB ROM. All flash chips in the system must be of the same +type. + +FLASH4 can use several different methods to access the Flash ROM chips. 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. + +FLASH4 will detect the presence of RomWBW, UNA BIOS or P112 B/P BIOS and use +the bank switching methods they provide to map in the flash memory. + +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] + + FLASH4 VERIFY filename [options] + + FLASH4 READ filename [options] + +The WRITE command 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. + +The VERIFY command 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. + +The READ command will read out the entire flash ROM contents and write it to +the named file. + +FLASH4 will auto-detect most parameters so additional options should not +normally be required. + +The "/V" (verbose) option makes FLASH4 print one line per sector, giving a +detailed log of what it did. + +The "/P" or "/PARTIAL" option can be used if your ROM chip is larger than the +image you wish to write and you only want to reprogram part of it. 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. + +The "/ROM" option can be used when you are using an ROM/EPROM/EEPROM chip which +cannot be programmed in-system and FLASH4 cannot recognise it. Only the "READ" +and "VERIFY" commands are supported with this option. This mode assumes a 512K +ROM is fitted, smaller ROMs will be treated as a 512KB ROM with the data +repeated multiple times. + +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. + +If RomWBW 2.6+ is in use, and correctly configured, then multiple flash chips +can be detected automatically. Multiple chip operation can also be manually +enabled using the command line options "/1", "/2", "/3" etc up to "/9" to +specify the number of flash chips to program. All flash chips in the system +must be of the same type. + + += Supported flash memory chips = + +FLASH4 will interrogate your flash ROM chip to identify it automatically. + +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 fully supported and will be programmed sector by +sector: + + 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, so FLASH4 +will only erase and reprogram the entire chip at once: + + AT49F001N + AT49F001NT + AT49F002N + AT49F002NT + AT49F040 + + += Compiling = + +The software is written in a mix of C and assembler. It builds using the SDCC +toolchain and the SRecord tools. SDCC 3.6 and 3.8 have been tested. 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 +installation is not in /usr/local or /usr + + += 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. diff --git a/Doc/FDU.txt b/Doc/FDU.txt index d67fe1fe..278d6686 100644 --- a/Doc/FDU.txt +++ b/Doc/FDU.txt @@ -510,5 +510,11 @@ WW 9/5/2018: v5.3 operation. - Added support for SmallZ80 -WW 5/1/2020: v5.4 +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 \ No newline at end of file diff --git a/Doc/Hard Disk Anatomy.pdf b/Doc/Hard Disk Anatomy.pdf index 54bf0ad5..a65a9912 100644 Binary files a/Doc/Hard Disk Anatomy.pdf and b/Doc/Hard Disk Anatomy.pdf differ diff --git a/Doc/RomWBW Applications.pdf b/Doc/RomWBW Applications.pdf index ed1cd38b..27775981 100644 Binary files a/Doc/RomWBW Applications.pdf and b/Doc/RomWBW Applications.pdf differ diff --git a/Doc/RomWBW Architecture.pdf b/Doc/RomWBW Architecture.pdf index 10bbc123..5a4c1402 100644 Binary files a/Doc/RomWBW Architecture.pdf and b/Doc/RomWBW Architecture.pdf differ diff --git a/Doc/RomWBW Disk Catalog.pdf b/Doc/RomWBW Disk Catalog.pdf new file mode 100644 index 00000000..7d0a6528 Binary files /dev/null and b/Doc/RomWBW Disk Catalog.pdf differ diff --git a/Doc/RomWBW Getting Started.pdf b/Doc/RomWBW Getting Started.pdf index dabf18a4..4bca51e3 100644 Binary files a/Doc/RomWBW Getting Started.pdf and b/Doc/RomWBW Getting Started.pdf differ diff --git a/Doc/SIO+CTC Baud Rate Options.pdf b/Doc/SIO+CTC Baud Rate Options.pdf new file mode 100644 index 00000000..923e6b48 Binary files /dev/null and b/Doc/SIO+CTC Baud Rate Options.pdf differ diff --git a/Makefile b/Makefile index 44d7847e..741e5ef7 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,18 @@ all: - cd Tools/unix ; make - cd Source ; make - cd Source/Images ; make + $(MAKE) --directory Tools/unix + $(MAKE) --directory Source clean: - cd Tools/unix ; make clean - cd Source ; make clean - cd Binary ; make clean + $(MAKE) --directory Tools/unix clean + $(MAKE) --directory Source clean + $(MAKE) --directory Binary clean clobber: - cd Tools/unix ; make clobber - cd Source ; make clobber - cd Binary ; make clobber + $(MAKE) --directory Tools/unix clobber + $(MAKE) --directory Source clobber + $(MAKE) --directory Binary clobber rm -f typescript diff: - cd Source ; make diff + $(MAKE) --directory Source diff diff --git a/ReadMe.md b/ReadMe.md index 8c4346c4..e7a8b863 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -3,7 +3,7 @@ ## Z80/Z180 System Software Version 3.1 Pre-release -Saturday 11 April 2020 +Friday 15 January 2021 Wayne Warthen @@ -37,7 +37,7 @@ General features include: - Disk drivers for RAM, ROM, Floppy, IDE, CF, and SD - Serial drivers including UART (16550-like), ASCI, ACIA, SIO - Video drivers including TMS9918, SY6545, MOS8563, HD6445 - - Real time clock drivers including DS1322, BQ4845 + - Real time clock drivers including DS1302, BQ4845 - Multiple OS support including CP/M 2.2, ZSDOS, CP/M 3, ZPM3 - Built-in VT-100 terminal emulation support @@ -311,7 +311,7 @@ media. You can think of slices as a way to refer to any of the first 256 Of course, the problem is that CP/M-like operating systems have only 16 drive letters (A:-P:) available. Under the covers, RomWBW allows you to use any drive letter to refer to any slice of any media. The `ASSIGN` -command is allows you to view or change the drive letter mappings at any +command allows you to view or change the drive letter mappings at any time. At startup, the operating system will automatically allocate a reasonable number of drive letters to the available storage devices. The allocation will depend on the number of large storage devices available @@ -706,13 +706,17 @@ most stable and you are less likely to encounter problems. ### Notes + - You can change media, but it must be done while at the OS command + prompt and you **must** warm start CP/M by pressing ctrl-c. This is + a CP/M 2.2 constraint and is well documented in the DRI manuals. + - The original versions of DDT, DDTZ, and ZSID used the RST 38 vector which conflicts with interrupt mode 1 use of this vector. The DDT, - DDTZ, and ZSID applications in RomWBW have been modified to use RTS + DDTZ, and ZSID applications in RomWBW have been modified to use RST 30 to avoid this issue. - Z-System applications will not run under CP/M 2.2. For example, the - `LDDS` date stamper with not run. + `LDDS` date stamper will not run. ## ZSDOS 1.1 @@ -735,6 +739,10 @@ Manual.pdf”). of the ZSDOS paths and will fail in some scenarios (use `COPY` instead). + - Although ZSDOS can recognize a media change in some cases, it will + not always work. You should only change media at a command prompt + and be sure to warm start the OS with a ctrl-c. + ## NZCOM Automatic Z-System NZCOM is a much further refined version of Z-System (ZCPR 3.4). NZCOM @@ -775,6 +783,16 @@ tracks. `CPMLDR.SYS` chain loads `CPM3.SYS`. used to read the current date/time for file stamping, etc. You can use the `RTC` app to set the RTC clock. + - The `COPYSYS` command described in the DRI CP/M 3 documentation is + not provided with RomWBW. The RomWBW `SYSCOPY` command is used + instead. + + - Although CP/M 3 is generally able to run CP/M 2.2 programs, this is + not universally true. This is especially true of the utility + programs included with the operating system. For example, the + `SUBMIT` program of CP/M 3 is completely different from the `SUBMIT` + program of CP/M 2.2. + ## Simeon Cran’s ZPM3 ZPM3 is an interesting combination of the features of both CP/M 3 and @@ -788,8 +806,9 @@ tracks of the disk. - `ZPMLDR` is included with ZPM3, but it is not working correctly. - The ZPM operating system is contained in the file called CPM3.SYS - which is confusing, but it is the author’s intended way of using - ZPM3. + which is confusing, but this is as intended by the ZPM3 + distribution. I believe it was done this way to make it easier for + users to transition from CP/M 3 to ZPM3. ## FreeRTOS @@ -1019,7 +1038,7 @@ system, you can use the FLASH application to update your ROM. The following is a typical example of transferring ROM image using XModem and flashing the chip in-situ. - E>xm r rom.img + E>xm r rom.rom XMODEM v12.5 - 07/13/86 RBC, 28-Aug-2019 [WBW], ASCI @@ -1031,7 +1050,7 @@ and flashing the chip in-situ. Thanks for the upload - E>flash write rom.img + E>flash write rom.rom FLASH4 by Will Sowerbutts version 1.2.3 Using RomWBW (v2.6+) bank switching. @@ -1060,12 +1079,76 @@ your choice. This process is described below in the Disk Images section. If you wish to update existing disk media in your system, you need to perform the following steps. -If the disk is bootable, you need to update the system tracks of the -disk. This is done using a SYSCOPY command such as `SYSCOPY -C:=B:ZSYS.SYS`. For a ZSDOS boot disk, use ZSYS.SYS. For a CP/M 2.2 -disk, use CPM.SYS. For a CP/M 3 or ZPM3 disk, use CPMLDR.SYS. CPMLDR.SYS -is not provided on the ROM disk, so you will need to upload it from the -distribution. +If the disk is bootable, you need to update the system image on the disk +using the procedure described below corresponsing to the operating +system on your disk. + + - **CP/M 2.2** + + Boot to CP/M 2.2 from ROM, then use `SYSCOPY` to update the system + image on **all** CP/M 2.2 boot disks/slices. The CP/M 2.2 system + image is called CPM.SYS and is found on the ROM disk. For example: + + `B>SYSCOPY C:=CPM.SYS` + + - **ZSDOS** + + Boot to Z-System from ROM, then use `SYSCOPY` to update the system + image on **all** ZSDOS boot disks/slices. The ZSDOS system image is + called ZSYS.SYS and is found on the ROM disk. For example: + + `B>SYSCOPY C:=ZSYS.SYS` + + - **NZCOM** + + NZCOM runs on top of either CP/M 2.2 or ZSDOS. By default, the + RomWBW disk image for NZCOM uses ZSDOS. Follow the corresponding + procedure above to update the system image on the NZCOM boot + disks/slices. + + - **CP/M 3** + + CP/M 3 uses a multi-step boot process involving multiple files. The + CP/M 3 boot files are not included on the ROM disk due to space + constraints. You will need to transfer the files to your system from + the RomWBW distribution directory Binary\\CPM3. + + After this is done, you will need to use `SYSCOPY` to place the CP/M + 3 loader image on the boot tracks of all CP/M 3 boot disks/slices. + The loader image is called `CPMLDR.SYS`. You must then copy (at a + minimum) `CPM3.SYS` and `CCP.COM` onto the disk/slice. Assuming you + copied the CP/M 3 boot files onto your RAM disk at A:, you would + use: + + A>B:SYSCOPY C:=CPMLDR.SYS + A>B:COPY CPM3.SYS C: + A>B:COPY CCP.COM C: + + - **ZPM3** + + ZPM3 uses a multi-step boot process involving multiple files. The + ZPM3 boot files are not included on the ROM disk due to space + constraints. You will need to transfer the files to your system from + the RomWBW distribution directory Binary\\ZPM3. + + After this is done, you will need to use `SYSCOPY` to place the ZPM3 + loader image on the boot tracks of all ZPM3 boot disks/slices. The + loader image is called `CPMLDR.SYS`. You must then copy (at a + minimum) `CPM3.SYS`, `ZCCP.COM`, `ZINSTAL.ZPM`, and `STARTZPM.COM` + onto the disk/slice. Assuming you copied the ZPM3 boot files onto + your RAM disk at A:, you would use: + + A>B:SYSCOPY C:=CPMLDR.SYS + A>B:COPY CPM3.SYS C: + A>B:COPY ZCCP.COM C: + A>B:COPY ZINSTAL.ZPM C: + A>B:COPY STARTZPM.COM C: + + You may be wondering if the references to `CPMLDR.SYS` and + `CPM3.SYS` are typos. They are not. ZPM3 uses the same loader image + as CPM3. The ZPM3 main system code file is called `CPM3.SYS` which + is the same name as CP/M 3 uses, but the file contents are not the + same. Finally, if you have copies of any of the RomWBW custom applications on your hard disk, you need to update them with the latest copies. The @@ -1096,6 +1179,36 @@ images. - FAT.COM - TUNE.COM +# System Update + +If the system running ROMWBW utilizes the SST39SF040 Flash chip then it +is possible to do a System Update in place of a System Upgrade in some +cases. + +A System Update would involve only updating the BIOS, ROM applications +and CP/M system. + +A System Update may be more favorable than a System Upgrade in cases +such as: + + - Overwriting of the ROM drive is not desired. + - Space is unavailable to hold a full ROMWBW ROM. + - To mimimize time taken to transfer and flash a full ROM. + - Configuration changes are only minor and do not impact disk + applications. + +The ROMWBW build process generates a system upgrade file along with the +normal ROM image and can be identified by the extension “.upd”. It will +be 128Kb in size. In comparison the normal ROM image will have the +extension “.rom” and be 512Kb or 1024Kb in size. + +Transferring and flashing the System Update is accomplished in the same +manner as described above in *Upgrading* with the required difference +being that the flash application needs to be directed to complete a +partial flash using the /p command line switch. + +`E>flash write rom.upd /p` + # RomWBW Distribution All source code and distributions are maintained on GitHub. Code @@ -1137,12 +1250,17 @@ applications are no longer provided. driver. - Ed Brindley contributed some of the code that supports the RC2014 platform. - - Phil Summers contributed Forth and BASIC in ROM as well as a long - list of general code enhancements. + - Phil Summers contributed Forth and BASIC in ROM, the AY-3-8910 sound + driver as well as a long list of general code enhancements. - Phillip Stevens contributed support for FreeRTOS. - Curt Mayer contributed the Linux / MacOS build process. - - UNA BIOS and FDISK80 is a product of John Coffman. + - UNA BIOS and FDISK80 are the products of John Coffman. - FLASH4 is a product of Will Sowerbutts. + - CLRDIR is a product of Max Scane. + - Tasty Basic is a product of Dimitri Theulings. + - Dean Netherton contributed the sound driver interface and the + SN76489 sound driver. + - The RomWBW Disk Catalog document was produced by Mykl Orders. Contributions of all kinds to RomWBW are very welcome. diff --git a/ReadMe.txt b/ReadMe.txt index f47dcf47..12c59c23 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -3,7 +3,7 @@ RomWBW Z80/Z180 System Software Version 3.1 Pre-release -Saturday 11 April 2020 +Friday 15 January 2021 Wayne Warthen wwarthen@gmail.com @@ -33,7 +33,7 @@ General features include: - Disk drivers for RAM, ROM, Floppy, IDE, CF, and SD - Serial drivers including UART (16550-like), ASCI, ACIA, SIO - Video drivers including TMS9918, SY6545, MOS8563, HD6445 -- Real time clock drivers including DS1322, BQ4845 +- Real time clock drivers including DS1302, BQ4845 - Multiple OS support including CP/M 2.2, ZSDOS, CP/M 3, ZPM3 - Built-in VT-100 terminal emulation support @@ -325,7 +325,7 @@ media. You can think of slices as a way to refer to any of the first 256 Of course, the problem is that CP/M-like operating systems have only 16 drive letters (A:-P:) available. Under the covers, RomWBW allows you to use any drive letter to refer to any slice of any media. The ASSIGN -command is allows you to view or change the drive letter mappings at any +command allows you to view or change the drive letter mappings at any time. At startup, the operating system will automatically allocate a reasonable number of drive letters to the available storage devices. The allocation will depend on the number of large storage devices available @@ -737,13 +737,17 @@ most stable and you are less likely to encounter problems. Notes +- You can change media, but it must be done while at the OS command + prompt and you must warm start CP/M by pressing ctrl-c. This is a + CP/M 2.2 constraint and is well documented in the DRI manuals. + - The original versions of DDT, DDTZ, and ZSID used the RST 38 vector which conflicts with interrupt mode 1 use of this vector. The DDT, - DDTZ, and ZSID applications in RomWBW have been modified to use RTS + DDTZ, and ZSID applications in RomWBW have been modified to use RST 30 to avoid this issue. - Z-System applications will not run under CP/M 2.2. For example, the - LDDS date stamper with not run. + LDDS date stamper will not run. ZSDOS 1.1 @@ -764,6 +768,10 @@ Notes of the ZSDOS paths and will fail in some scenarios (use COPY instead). +- Although ZSDOS can recognize a media change in some cases, it will + not always work. You should only change media at a command prompt + and be sure to warm start the OS with a ctrl-c. + NZCOM Automatic Z-System NZCOM is a much further refined version of Z-System (ZCPR 3.4). NZCOM @@ -804,6 +812,15 @@ Notes to read the current date/time for file stamping, etc. You can use the RTC app to set the RTC clock. +- The COPYSYS command described in the DRI CP/M 3 documentation is not + provided with RomWBW. The RomWBW SYSCOPY command is used instead. + +- Although CP/M 3 is generally able to run CP/M 2.2 programs, this is + not universally true. This is especially true of the utility + programs included with the operating system. For example, the SUBMIT + program of CP/M 3 is completely different from the SUBMIT program of + CP/M 2.2. + Simeon Cran’s ZPM3 ZPM3 is an interesting combination of the features of both CP/M 3 and @@ -817,8 +834,9 @@ Notes - ZPMLDR is included with ZPM3, but it is not working correctly. - The ZPM operating system is contained in the file called CPM3.SYS - which is confusing, but it is the author’s intended way of using - ZPM3. + which is confusing, but this is as intended by the ZPM3 + distribution. I believe it was done this way to make it easier for + users to transition from CP/M 3 to ZPM3. FreeRTOS @@ -1043,7 +1061,7 @@ system, you can use the FLASH application to update your ROM. The following is a typical example of transferring ROM image using XModem and flashing the chip in-situ. - E>xm r rom.img + E>xm r rom.rom XMODEM v12.5 - 07/13/86 RBC, 28-Aug-2019 [WBW], ASCI @@ -1055,7 +1073,7 @@ and flashing the chip in-situ. Thanks for the upload - E>flash write rom.img + E>flash write rom.rom FLASH4 by Will Sowerbutts version 1.2.3 Using RomWBW (v2.6+) bank switching. @@ -1084,12 +1102,74 @@ your choice. This process is described below in the Disk Images section. If you wish to update existing disk media in your system, you need to perform the following steps. -If the disk is bootable, you need to update the system tracks of the -disk. This is done using a SYSCOPY command such as -SYSCOPY C:=B:ZSYS.SYS. For a ZSDOS boot disk, use ZSYS.SYS. For a CP/M -2.2 disk, use CPM.SYS. For a CP/M 3 or ZPM3 disk, use CPMLDR.SYS. -CPMLDR.SYS is not provided on the ROM disk, so you will need to upload -it from the distribution. +If the disk is bootable, you need to update the system image on the disk +using the procedure described below corresponsing to the operating +system on your disk. + +- CP/M 2.2 + + Boot to CP/M 2.2 from ROM, then use SYSCOPY to update the system + image on all CP/M 2.2 boot disks/slices. The CP/M 2.2 system image + is called CPM.SYS and is found on the ROM disk. For example: + + B>SYSCOPY C:=CPM.SYS + +- ZSDOS + + Boot to Z-System from ROM, then use SYSCOPY to update the system + image on all ZSDOS boot disks/slices. The ZSDOS system image is + called ZSYS.SYS and is found on the ROM disk. For example: + + B>SYSCOPY C:=ZSYS.SYS + +- NZCOM + + NZCOM runs on top of either CP/M 2.2 or ZSDOS. By default, the + RomWBW disk image for NZCOM uses ZSDOS. Follow the corresponding + procedure above to update the system image on the NZCOM boot + disks/slices. + +- CP/M 3 + + CP/M 3 uses a multi-step boot process involving multiple files. The + CP/M 3 boot files are not included on the ROM disk due to space + constraints. You will need to transfer the files to your system from + the RomWBW distribution directory Binary\CPM3. + + After this is done, you will need to use SYSCOPY to place the CP/M 3 + loader image on the boot tracks of all CP/M 3 boot disks/slices. The + loader image is called CPMLDR.SYS. You must then copy (at a minimum) + CPM3.SYS and CCP.COM onto the disk/slice. Assuming you copied the + CP/M 3 boot files onto your RAM disk at A:, you would use: + + A>B:SYSCOPY C:=CPMLDR.SYS + A>B:COPY CPM3.SYS C: + A>B:COPY CCP.COM C: + +- ZPM3 + + ZPM3 uses a multi-step boot process involving multiple files. The + ZPM3 boot files are not included on the ROM disk due to space + constraints. You will need to transfer the files to your system from + the RomWBW distribution directory Binary\ZPM3. + + After this is done, you will need to use SYSCOPY to place the ZPM3 + loader image on the boot tracks of all ZPM3 boot disks/slices. The + loader image is called CPMLDR.SYS. You must then copy (at a minimum) + CPM3.SYS, ZCCP.COM, ZINSTAL.ZPM, and STARTZPM.COM onto the + disk/slice. Assuming you copied the ZPM3 boot files onto your RAM + disk at A:, you would use: + + A>B:SYSCOPY C:=CPMLDR.SYS + A>B:COPY CPM3.SYS C: + A>B:COPY ZCCP.COM C: + A>B:COPY ZINSTAL.ZPM C: + A>B:COPY STARTZPM.COM C: + + You may be wondering if the references to CPMLDR.SYS and CPM3.SYS + are typos. They are not. ZPM3 uses the same loader image as CPM3. + The ZPM3 main system code file is called CPM3.SYS which is the same + name as CP/M 3 uses, but the file contents are not the same. Finally, if you have copies of any of the RomWBW custom applications on your hard disk, you need to update them with the latest copies. The @@ -1119,6 +1199,36 @@ Binary\Apps directory of the distribution and in all of the disk images. - FAT.COM - TUNE.COM +System Update + +If the system running ROMWBW utilizes the SST39SF040 Flash chip then it +is possible to do a System Update in place of a System Upgrade in some +cases. + +A System Update would involve only updating the BIOS, ROM applications +and CP/M system. + +A System Update may be more favorable than a System Upgrade in cases +such as: + +- Overwriting of the ROM drive is not desired. +- Space is unavailable to hold a full ROMWBW ROM. +- To mimimize time taken to transfer and flash a full ROM. +- Configuration changes are only minor and do not impact disk + applications. + +The ROMWBW build process generates a system upgrade file along with the +normal ROM image and can be identified by the extension “.upd”. It will +be 128Kb in size. In comparison the normal ROM image will have the +extension “.rom” and be 512Kb or 1024Kb in size. + +Transferring and flashing the System Update is accomplished in the same +manner as described above in Upgrading with the required difference +being that the flash application needs to be directed to complete a +partial flash using the /p command line switch. + +E>flash write rom.upd /p + RomWBW Distribution All source code and distributions are maintained on GitHub. Code @@ -1169,12 +1279,17 @@ applications are no longer provided. driver. - Ed Brindley contributed some of the code that supports the RC2014 platform. -- Phil Summers contributed Forth and BASIC in ROM as well as a long - list of general code enhancements. +- Phil Summers contributed Forth and BASIC in ROM, the AY-3-8910 sound + driver as well as a long list of general code enhancements. - Phillip Stevens contributed support for FreeRTOS. - Curt Mayer contributed the Linux / MacOS build process. -- UNA BIOS and FDISK80 is a product of John Coffman. +- UNA BIOS and FDISK80 are the products of John Coffman. - FLASH4 is a product of Will Sowerbutts. +- CLRDIR is a product of Max Scane. +- Tasty Basic is a product of Dimitri Theulings. +- Dean Netherton contributed the sound driver interface and the + SN76489 sound driver. +- The RomWBW Disk Catalog document was produced by Mykl Orders. Contributions of all kinds to RomWBW are very welcome. diff --git a/Readme.unix b/Readme.unix index 710487c6..5a7c3b94 100644 --- a/Readme.unix +++ b/Readme.unix @@ -1,49 +1,87 @@ -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. +This tree now contains makefiles and tools to build on Linux and +macOS. Linux is rather more thoroughly tested compared to macOS. + +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 + .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". + +By default, this will generate all of the standard configurations of +RomWBW for all platforms. If you just want to build the ROM for a +specific platform and configuration you can use -it assumes that you have some standard system tools and libraries installed -specifically: gcc, gnu make, libncurses + make ROM_PLATFORM= ROM_CONFIG= -to build: - cd to the top directory and type make. +where is one of the supported platforms such as SBC, RCZ80, +etc. and is a configuration of that platform. For example, +to build the "126" configuration of the "SCZ180" platform: -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. + make ROM_PLATFORM=SCZ180 ROM_CONFIG=126 -these tools can run a windows-linux regression test, where all the binaries are -compared to a baseline windows build. +For macOS users, you may encounter a failure reading or writing files. +This is caused by protection features in macOS (at least, in Catalina) +that prevent programs built on your local system (unsigned) from +running. To disable this feature: + +1) Make sure you exit System Preferences. +2) Open a terminal session and type the following. You will need to + authenticate with an admin account. sudo spctl --master-disable +3) Exit terminal +4) Go into System Preferences and choose Security and Privacy +5) Select the General tab if it isn't already selected +6) You should now see a third selection under + "Allow apps downloaded from:" of Anywhere - select this. +7) Now you can run the build successfully. + +DISCLAIMER: You do this at your own risk. I highly recommend that you +return the settings back to normal immediately after doing a build. + +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 + 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 macOS. - 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. - 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 the distributed version, and also has local hacks + for case insensitivity. - 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. + 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. + 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. diff --git a/Source/Apps/Assign.asm b/Source/Apps/Assign.asm index 0bbf038e..c080991b 100644 --- a/Source/Apps/Assign.asm +++ b/Source/Apps/Assign.asm @@ -22,7 +22,11 @@ ; 2016-04-08 [WBW] Determine key memory addresses dynamically ; 2019-08-07 [WBW] Fixed DPB selection error ; 2019-11-17 [WBW] Added preliminary CP/M 3 support -; 2019-12-24 [WBW] Fixed location of BIOS save area +; 2019-12-24 [WBW] Fixed location of BIOS save area\ +; 2020-04-29 [WBW] Updated for larger DPH (16 -> 20 bytes) +; 2020-05-06 [WBW] Add patch level to version compare +; 2020-05-10 [WBW] Set media change flag in XDPH for CP/M 3 +; 2020-05-12 [WBW] Back out media change flag ;_______________________________________________________________________________ ; ; ToDo: @@ -41,8 +45,7 @@ bdos .equ $0005 ; BDOS invocation vector ; stamp .equ $40 ; loc of RomWBW CBIOS zero page stamp ; -rmj .equ 3 ; CBIOS version - major -rmn .equ 1 ; CBIOS version - minor +#include "../ver.inc" ; ;=============================================================================== ; Code Section @@ -118,10 +121,14 @@ init: jp nz,errinv ; abort with invalid config block inc hl ; next byte (major/minor version) ld a,(hl) ; load it - cp rmj << 4 | rmn ; match? + cp RMJ << 4 | RMN ; match? jp nz,errver ; abort with invalid os version - inc hl ; bump past - inc hl ; ... version info + inc hl ; next byte (update/patch) + ld a,(hl) ; load it + and $F0 ; eliminate patch num + cp RUP << 4 ; match? + jp nz,errver ; abort with invalid os version + inc hl ; bump past version info ; ; dereference HL to point to CBIOS extension data ld a,(hl) ; dereference HL @@ -546,7 +553,8 @@ dph_init2: ld a,(hl) ; unit to A push bc ; save loop control push hl ; save drive map pointer - ld hl,16 ; size of a DPH structure + ;ld hl,16 ; size of a DPH structure + ld hl,20 ; size of a DPH structure call alloc ; allocate space for dph jp c,instovf ; handle overflow error push hl ; save DPH location @@ -771,6 +779,10 @@ instc2: inc hl ; bump to slice field of DPH field ld a,(de) ; get slice from mapwrk ld (hl),a ; put slice into DPH field +; ld a,11 ; media byte is 11 bytes ahead +; call addhl ; bump HL to media byte adr +; or $FF ; use $FF to signify media change +; ld (hl),a ; set media flag byte inc de ; bump to next mapwrk entry inc de ; ... inc de ; ... @@ -781,7 +793,7 @@ instc3: push hl ; save drvtbl entry adr push de ; save mapwrk entry adr ld hl,(dphadr) ; get cur dph address - ld de,$23 ; size of xdph + ld de,$27 ; size of xdph add hl,de ; bump to next dph ld (dphadr),hl ; save it pop de ; recover mapwrk entry adr @@ -794,6 +806,16 @@ instc3: add hl,de ; HL := SELMEM func ld a,1 ; bank 1 is tpa bank call jphl +; + ; set SCB drive door open flag + ld a,$54 ; SCB drive door opened flag + ld (scboff),a ; set offset parm + or $FF ; SCB operation, $FF = set + ld (scbop),a ; set operation parm + ld (scbval),a ; set value parm to $FF + ld c,$31 ; get/set system control block + ld de,scbpb ; scb parameter block adr + call bdos ; call drvrst ; perform BDOS drive reset ; @@ -1822,6 +1844,11 @@ heaplim .dw 0 ; heap limit address ; dirbuf .dw 0 ; directory buffer location ; +scbpb: ; BDOS SCB get/set parm block +scboff .db $54 ; media open door flag +scbop .db $FF ; set a byte +scbval .dw $FF ; value to set +; mapwrk .fill (4 * 16),$FF ; working copy of drive map ; devtbl: ; device table @@ -1866,10 +1893,10 @@ stack .equ $ ; stack top ; Messages ; indent .db " ",0 -msgban1 .db "ASSIGN v1.1a for RomWBW CP/M, 24-Dec-2019",0 +msgban1 .db "ASSIGN v1.4 for RomWBW CP/M, 12-May-2020",0 msghb .db " (HBIOS Mode)",0 msgub .db " (UBIOS Mode)",0 -msgban2 .db "Copyright 2019, Wayne Warthen, GNU GPL v3",0 +msgban2 .db "Copyright 2020, Wayne Warthen, GNU GPL v3",0 msguse .db "Usage: ASSIGN D:[=[{D:|[]:[]}]][,...]",13,10 .db " ex. ASSIGN (display all active assignments)",13,10 .db " ASSIGN /? (display version and usage)",13,10 diff --git a/Source/Apps/FDU/FDU.asm b/Source/Apps/FDU/FDU.asm index da176f06..9b7a5620 100644 --- a/Source/Apps/FDU/FDU.asm +++ b/Source/Apps/FDU/FDU.asm @@ -45,6 +45,8 @@ ; - USE EOT=R TO END R/W AFTER ONE SECTOR INSTEAD ; OF USING PULSE TC ; 2020-01-05: V5.4 ADDED SUPPORT FOR DYNO FDC +; 2020-04-29: v5.5 ADDED SUPPORT FOR ETCHED PIXELS FDC +; 2020-12-12: v5.6 UPDATED SMALLZ80 TO NEW I/O ADDRESSES ; ;_______________________________________________________________________________ ; @@ -79,6 +81,7 @@ FDC_RCSMC .EQU 6 FDC_RCWDC .EQU 7 FDC_SMZ80 .EQU 8 FDC_DYNO .EQU 9 +FDC_EPFDC .EQU 10 ; ; FDC MODE ; @@ -213,7 +216,7 @@ INIT5: XOR A RET -STR_BANNER .DB "Floppy Disk Utility (FDU) v5.4, 05-jAN-2020$" +STR_BANNER .DB "Floppy Disk Utility (FDU) v5.6, 12-Dec-2020$" STR_BANNER2 .DB "Copyright (C) 2020, Wayne Warthen, GNU GPL v3","$" STR_HBIOS .DB " [HBIOS]$" STR_UBIOS .DB " [UBIOS]$" @@ -284,6 +287,7 @@ FDCTBL: ; LABEL CONFIG DATA .DW STR_RCWDC, CFG_RCWDC .DW STR_SMZ80, CFG_SMZ80 .DW STR_DYNO, CFG_DYNO + .DW STR_EPFDC, CFG_EPFDC FDCCNT .EQU ($-FDCTBL)/4 ; FD CONTROLLER COUNT ; ; FDC LABEL STRINGS @@ -298,6 +302,7 @@ STR_RCSMC .TEXT "RC-SMC$" STR_RCWDC .TEXT "RC-WDC$" STR_SMZ80 .TEXT "SMZ80$" STR_DYNO .TEXT "DYNO$" +STR_EPFDC .TEXT "EPFDC$" ; ; FDC CONFIGURATION BLOCKS ; @@ -398,11 +403,11 @@ CFG_RCWDC: .DB _PCAT ; MODE= ; CFG_SMZ80: - .DB 044H ; FDC MAIN STATUS REGISTER - .DB 045H ; FDC DATA PORT + .DB 074H ; FDC MAIN STATUS REGISTER + .DB 075H ; FDC DATA PORT .DB 0FFH ; DATA INPUT REGISTER - .DB 042H ; DIGITAL OUTPUT REGISTER (LATCH) - .DB 047H ; DCR + .DB 072H ; DIGITAL OUTPUT REGISTER (LATCH) + .DB 077H ; DCR .DB 0FFH ; DACK .DB 0FFH ; TERMINAL COUNT (W/ DACK) .DB 0FFH ; PSEUDO DMA DATA PORT @@ -419,6 +424,17 @@ CFG_DYNO: .DB 0FFH ; PSEUDO DMA DATA PORT .DB _PCAT ; MODE= ; +CFG_EPFDC: + .DB 048H ; FDC MAIN STATUS REGISTER + .DB 049H ; FDC DATA PORT + .DB 0FFH ; DATA INPUT REGISTER + .DB 04AH ; DIGITAL OUTPUT REGISTER (LATCH) + .DB 04BH ; DCR + .DB 0FFH ; DACK + .DB 04CH ; TERMINAL COUNT (W/ DACK) + .DB 0FFH ; PSEUDO DMA DATA PORT + .DB _PCAT ; MODE= +; FDCID .DB 0 ; FDC IDENTIFIER (0 INDEXED) FDCBM .DB 0 ; FDC ID BITMAP FDCLBL .DW 0 ; POINTER TO ACTIVE FDC LABEL STRING @@ -437,6 +453,7 @@ FSS_MENU: .TEXT " (H) RC2014 WDC (SMB)\r\n" .TEXT " (I) SmallZ80 Expansion\r\n" .TEXT " (J) Dyno-Card FDC, D1030\r\n" + .TEXT " (K) RC2014 EPFDC\r\n" .TEXT " (X) Exit\r\n" .TEXT "=== OPTION ===> $\r\n" ; @@ -1517,6 +1534,7 @@ MD_MAP: .DB %00000001 ; RCWDC POLL .DB %00000001 ; SMZ80 POLL .DB %00000001 ; DYNO POLL + .DB %00000001 ; EPFDC POLL ; ; MEDIA DESCRIPTION BLOCK ; @@ -1877,7 +1895,7 @@ FM_DRAW0B: ; ZETA, DIO3 LD A,(FST_DOR) AND 00000010B JR FM_DRAW1 -FM_DRAW0C: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO +FM_DRAW0C: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO, EPFDC LD A,(FST_DOR) AND 11110000B JR FM_DRAW1 @@ -2030,7 +2048,7 @@ FM_MOTOR0B: ; ZETA, DIO3 LD A,(FST_DOR) AND 00000010B JR FM_MOTOR1 -FM_MOTOR0C: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO +FM_MOTOR0C: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO, EPFDC LD A,(FST_DOR) AND 11110000B JR FM_MOTOR1 @@ -2769,7 +2787,7 @@ FC_INIT1: ; DIO FC_INIT2: ; ZETA, DIO3 LD A,(FCD_DORB) JR FC_INIT5 -FC_INIT3: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO +FC_INIT3: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO, EPFDC LD A,(FCD_DORC) JR FC_INIT5 FC_INIT4: ; WDSMC @@ -2813,7 +2831,7 @@ FC_RESETFDC1: ; ZETA, DIO3, RCSMC POP AF OUT (C),A JR FC_RESETFDC3 -FC_RESETFDC2: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO +FC_RESETFDC2: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO, EPFDC LD A,0 OUT (C),A LD A,(FST_DOR) @@ -2840,7 +2858,7 @@ FC_PULSETC: ;RES 0,A ;OUT (C),A ;JR FC_PULSETC2 -;FC_PULSETC1: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO +;FC_PULSETC1: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO, EPFDC ;LD C,(IY+CFG_TC) ;IN A,(C) ;JR FC_PULSETC2 @@ -2872,7 +2890,7 @@ FC_MOTORON2: ; ZETA, DIO3 LD HL,FST_DOR ; POINT TO FDC_DOR SET 1,(HL) JR FC_MOTORON5 -FC_MOTORON3: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO +FC_MOTORON3: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO, EPFDC LD HL,FST_DOR ; POINT TO FDC_DOR LD A,(HL) ; START WITH CURRENT DOR AND 11111100B ; GET RID OF ANY ACTIVE DS BITS @@ -2936,7 +2954,7 @@ FC_MOTOROFF2: ; ZETA, DIO3 LD HL,FST_DOR ; POINT TO FDC_DOR RES 1,(HL) JR FC_MOTOROFF5 -FC_MOTOROFF3: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO +FC_MOTOROFF3: ; DIDE, N8, ZETA2, RCWDC, SMZ80, DYNO, EPFDC LD HL,FST_DOR ; POINT TO FDC_DOR LD A,DORC_INIT LD (HL),A @@ -3806,7 +3824,7 @@ DORB_BR500 .EQU 10100000B ; 500KBPS ; DORB_INIT .EQU DORB_BR250 ; -; *** DIDE/N8/ZETA2/RCWDC/SMZ80/DYNO *** +; *** DIDE/N8/ZETA2/RCWDC/SMZ80/DYNO/EPFDC *** ; DORC_INIT .EQU 00001100B ; SOFT RESET INACTIVE, DMA ENABLED ; diff --git a/Source/Apps/FDU/FDU.txt b/Source/Apps/FDU/FDU.txt index d67fe1fe..278d6686 100644 --- a/Source/Apps/FDU/FDU.txt +++ b/Source/Apps/FDU/FDU.txt @@ -510,5 +510,11 @@ WW 9/5/2018: v5.3 operation. - Added support for SmallZ80 -WW 5/1/2020: v5.4 +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 \ No newline at end of file diff --git a/Source/Apps/RTC.asm b/Source/Apps/RTC.asm index 5d731612..2d72482b 100644 --- a/Source/Apps/RTC.asm +++ b/Source/Apps/RTC.asm @@ -25,6 +25,8 @@ ; ;[2020/02/02] v1.5 PMS Basic command line support ; +;[2020/05/15] v1.6 Added Warm Start option +; ; Constants ; mask_data .EQU %10000000 ; RTC data line @@ -43,8 +45,14 @@ PORT_EZZ80 .EQU $C0 ; RTC port for EZZ80 (actually does not have one!!!) BDOS .EQU 5 ; BDOS invocation vector FCB .EQU 05CH ; Start of command line -BID_BOOT .EQU $00 -HB_BNKCALL .EQU $FFF9 +;BID_BOOT .EQU $00 +;HB_BNKCALL .EQU $FFF9 + +BF_SYSRESET .EQU $F0 ; RESTART SYSTEM + +BF_SYSRES_INT .EQU $00 ; RESET HBIOS INTERNAL +BF_SYSRES_WARM .EQU $01 ; WARM START (RESTART BOOT LOADER) +BF_SYSRES_COLD .EQU $02 ; COLD START ; ; Program @@ -1273,6 +1281,9 @@ RTC_UCL: CP 'B' JP Z,RTC_TOP_LOOP_BOOT + CP 'W' + JP Z,RTC_TOP_LOOP_WARMSTART + CP 'C' JP Z,RTC_TOP_LOOP_CHARGE @@ -1320,9 +1331,15 @@ DELAY_LOOP: ; LOOP IS 26TS OR L ; 4TS JR NZ,DELAY_LOOP ; 12TS ; RESTART SYSTEM FROM ROM BANK 0, ADDRESS $0000 - LD A,BID_BOOT ; BOOT BANK - LD HL,0 ; ADDRESS ZERO - CALL HB_BNKCALL ; DOES NOT RETURN + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_COLD ; COLD START + CALL $FFF0 ; CALL HBIOS + + +RTC_TOP_LOOP_WARMSTART: + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_WARM ; WARM START + CALL $FFF0 ; CALL HBIOS RTC_TOP_LOOP_CHARGE: LD DE,RTC_TOP_LOOP1_CHARGE @@ -1580,7 +1597,7 @@ RTC_HELP_MSG: .DB 0Ah, 0Dh ; line feed and carriage return .TEXT "RTC: Version 1.5" .DB 0Ah, 0Dh ; line feed and carriage return - .TEXT "Commands: E)xit T)ime st(A)rt S)et R)aw L)oop C)harge N)ocharge D)elay I)nit G)et P)ut B)oot H)elp" + .TEXT "Commands: E)xit T)ime st(A)rt S)et R)aw L)oop C)harge N)ocharge D)elay I)nit G)et P)ut B)oot W)arm-start H)elp" .DB 0Ah, 0Dh ; line feed and carriage return .DB "$" ; Line terminator diff --git a/Source/Apps/Survey.asm b/Source/Apps/Survey.asm index 33c71236..f049be90 100644 --- a/Source/Apps/Survey.asm +++ b/Source/Apps/Survey.asm @@ -600,9 +600,11 @@ PORTLP: 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 +; inactive port could return 0xFF or 0x78 or the port address + cmp c + jz nextpt + cpi 0FFh + jz nextpt cpi 078h jz nextpt ISPORT: diff --git a/Source/Apps/SysCopy.asm b/Source/Apps/SysCopy.asm index 144f9536..10b85bd2 100644 --- a/Source/Apps/SysCopy.asm +++ b/Source/Apps/SysCopy.asm @@ -17,6 +17,7 @@ ; Change Log: ; 2016-04-24 [WBW] Updated to preserve MBR partition table ; 2020-02-17 [WBW] Updated for CP/M 3 +; 2020-05-16 [WBW] Fixed SPT for CP/M 3 ;_______________________________________________________________________________ ; ; ToDo: @@ -441,6 +442,16 @@ setdsk: ld c,(hl) inc hl ld b,(hl) ; BC := sectors per track + ; handle CP/M 3 physical sector size + ld a,(v3os) ; CP/M 3 or greater? + or a ; set flags + jr z,setdsk1 ; if not, continue + ; adjust SPT for CP/M 3 physical sector size + srl b ; divide SPT by 4 + rr c + srl b + rr c +setdsk1: 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 @@ -952,7 +963,7 @@ bpb_hl .dw 0 ; reg HL ; ; Messages ; -msgban1 .db "SYSCOPY v2.0 for RomWBW CP/M, 17-Feb-2020$" +msgban1 .db "SYSCOPY v2.1 for RomWBW CP/M, 15-May-2020$" msgv2 .db " (CP/M 2 Mode)$" msgv3 .db " (CP/M 3 Mode)$" msgban2 .db "Copyright 2020, Wayne Warthen, GNU GPL v3$" diff --git a/Source/Apps/Timer.asm b/Source/Apps/Timer.asm index 0d049a06..e8d21740 100644 --- a/Source/Apps/Timer.asm +++ b/Source/Apps/Timer.asm @@ -41,8 +41,11 @@ rmn .equ 1 ; intended CBIOS version - minor ; bf_sysver .equ $F1 ; BIOS: VER function bf_sysget .equ $F8 ; HBIOS: SYSGET function +bf_sysset .equ $F9 ; HBIOS: SYSGET function bf_sysgettimer .equ $D0 ; TIMER subfunction +bf_syssettimer .equ $D0 ; TIMER subfunction bf_sysgetsecs .equ $D1 ; SECONDS subfunction +bf_syssetsecs .equ $D1 ; SECONDS subfunction ; ;=============================================================================== ; Code Section @@ -106,6 +109,15 @@ process00: jr process00 ; continue looking for options ; process0: +; + ; Test of API function to set seconds value + ;ld b,bf_sysset ; HBIOS SYSGET function + ;ld c,bf_syssetsecs ; SECONDS subfunction + ;ld de,0 ; set seconds value + ;ld hl,1000 ; ... to 1000 + ;rst 08 ; call HBIOS, DE:HL := seconds value +; + ; get and print seconds value call crlf2 ; formatting ; process1: diff --git a/Source/Apps/Tune/Build.cmd b/Source/Apps/Tune/Build.cmd index 568f73dc..82fa4c33 100644 --- a/Source/Apps/Tune/Build.cmd +++ b/Source/Apps/Tune/Build.cmd @@ -5,9 +5,11 @@ set TOOLS=../../../Tools set PATH=%TOOLS%\tasm32;%PATH% set TASMTABS=%TOOLS%\tasm32 -tasm -t180 -g3 -fFF Tune.asm Tune.com Tune.lst +tasm -t180 -g3 -fFF -dWBW Tune.asm Tune.com Tune.lst +tasm -t180 -g3 -fFF -dZX Tune.asm Tunezx.com Tunezx.lst +tasm -t180 -g3 -fFF -dMSX Tune.asm Tunemsx.com Tunemsx.lst if errorlevel 1 goto :eof -copy /Y Tune.com ..\..\..\Binary\Apps\ +copy /Y Tune*.com ..\..\..\Binary\Apps\ copy /Y Tunes\*.* ..\..\..\Binary\Apps\Tunes\ \ No newline at end of file diff --git a/Source/Apps/Tune/Makefile b/Source/Apps/Tune/Makefile index 3aa5c338..3f6c8fdb 100644 --- a/Source/Apps/Tune/Makefile +++ b/Source/Apps/Tune/Makefile @@ -1,11 +1,19 @@ -OBJECTS = Tune.com +OBJECTS = Tune.com Tunezx.com Tunemsx.com DEST = ../../../Binary/Apps TOOLS = ../../../Tools include $(TOOLS)/Makefile.inc -Tune.com: Tune.asm - $(TASM) Tune.asm Tune.com +DEPS := Tune.asm $(shell find . -name '*.inc') + +Tune.com: $(DEPS) + $(TASM) -dWBW Tune.asm Tune.com Tune.lst + +Tunezx.com: $(DEPS) + $(TASM) -dZX Tune.asm Tunezx.com Tunezx.lst + +Tunemsx.com: $(DEPS) + $(TASM) -dMSX Tune.asm Tunemsx.com Tunemsx.lst all:: mkdir -p $(DEST)/Tunes diff --git a/Source/Apps/Tune/Tune.asm b/Source/Apps/Tune/Tune.asm index 046b83ac..66ad34cd 100644 --- a/Source/Apps/Tune/Tune.asm +++ b/Source/Apps/Tune/Tune.asm @@ -39,6 +39,9 @@ ; 2019-11-21 [WBW] Added table-driven configuration ; 2020-02-11 [WBW] Made hardware config & detection more flexible ; 2020-03-29 [WBW] Fix error in Z180 I/O W/S bracketing +; 2020-04-25 [DEN] Added support to use HBIOS Sound driver +; 2020-05-02 [PMS] Add support for SBC-V2 slow-io hack +; 2020-09-03 [E?B] Add support for Ed Brindley YM/AY Sound Card v6 ;_______________________________________________________________________________ ; ; ToDo: @@ -49,18 +52,9 @@ ; Main program ;=============================================================================== ; -RESTART .EQU $0000 ; CP/M restart vector -BDOS .EQU $0005 ; BDOS invocation vector -; -IDENT .EQU $FFFE ; loc of RomWBW HBIOS ident ptr -; -RMJ .EQU 3 ; intended CBIOS version - major -RMN .EQU 1 ; intended CBIOS version - minor -; -BF_SYSVER .EQU $F1 ; BIOS: VER function -BF_SYSGET .EQU $F8 ; HBIOS: SYSGET function -; -FCB .EQU $5C ; Location of default FCB +#include "hbios.inc" +#include "cpm.inc" +#include "tune.inc" ; HEAPEND .EQU $C000 ; End of heap storage ; @@ -68,24 +62,58 @@ TYPPT2 .EQU 1 ; FILTYP value for PT2 sound file TYPPT3 .EQU 2 ; FILTYP value for PT3 sound file TYPMYM .EQU 3 ; FILTYP value for MYM sound file ; +; HIGH SPEED CPU CONTROL ; +SBCV2004 .EQU 0 ; USE SBC-V2-004 HALF CLOCK DIVIDER +CPUFAMZ180 .EQU 1 ; USE Z180 WAIT STATE MANAGEMENT ; +;Conditional assembly - use -D switch on TASM or uz80as assembler to control +_ZX .EQU 0 ; 1) Version of ROUT (ZX or MSX standards) +_MSX .EQU 0 +_WBW .EQU 0 +HBIOS .EQU 0 +#IFDEF ZX +_ZX .SET 1 +#ELSE +#IFDEF MSX +_MSX .SET 1 +#ELSE +_WBW .SET 1 + +#ENDIF +#ENDIF + +CurPosCounter .EQU 0 ; 2) Current position counter at (START+11) +ACBBAC .EQU 0 ; 3) Allow channels allocation bits at (START+10) +LoopChecker .EQU 1 ; 4) Allow loop checking and disabling +Id .EQU 1 ; 5) Insert official identificator +#DEFINE Release "1" ; Release number + .ORG $0100 ; - CALL CRLF - LD DE,MSGBAN ; Point to banner message - CALL PRTSTR ; Print message -; - ; Check BIOS and version + PRTCRLF + PRTSTRDE(MSGBAN) ; Print to banner message + + CALL CLI_ABRT_IF_OPT_FIRST + CALL CLI_HAVE_HBIOS_SWITCH + CALL CLI_OCTAVE_ADJST + JP CONTINUE + +CONTINUE: + ; Check BIOS and version CALL IDBIO ; Identify hardware BIOS CP 1 ; RomWBW HBIOS? - JP NZ,ERRBIO ; If not, handle BIOS error - LD A,RMJ << 4 | RMN ; Expected HBIOS ver + JP NZ, ERRBIO ; If not, handle BIOS error + LD A, RMJ << 4 | RMN ; Expected HBIOS ver CP D ; Compare with result above - JP NZ,ERRBIO ; Handle BIOS error - LD A,L ; Platform id to A + JP NZ, ERRBIO ; Handle BIOS error + LD A, L ; Platform id to A LD (CURPLT),A ; Save as current platform id -; + + LD A, (HBIOSMD) + OR A + JR NZ, TSTTIMER ; skip hardware check if using hbios + LD HL,CFGTBL ; Point to start of config table CFGSEL: LD A,$FF ; End of table marker @@ -111,7 +139,7 @@ CFGSEL: LD C,A ; Put in C for I/O LD A,$FF ; Value to activate card OUT (C),A ; Write value to ACR -; +; PROBE: ; Test for hardware (sound chip detection) LD DE,(PORTS) ; D := RDAT, E := RSEL @@ -137,21 +165,9 @@ MAT: LD DE,(DESC) ; Load hardware description pointer CALL PRTSTR ; Print description ; - ; Test for timer running to determine if it can be used for delay - LD B,BF_SYSGET ; HBIOS: GET function - LD C,$D0 ; TIMER subfunction - RST 08 ; DE:HL := current tick count - LD A,L ; DE:HL == 0? - OR H - OR E - OR D - LD A,0 ; Assume no timer - LD DE,MSGDLY ; Delay mode msg - JR Z,SETDLY ; If tick count is zero, no timer active - LD A,$FF ; Value for timer active - LD DE,MSGTIM ; Timer mode msg -SETDLY: - LD (WMOD),A ; Save wait mode + +TSTTIMER: + CALL PROBETIMER CALL PRTSTR ; Print it ; ; Get CPU speed & type from RomWBW HBIOS and compute quark delay factor @@ -170,7 +186,7 @@ SETDLY: LD DE,HEAP+1 ; Set dest to next byte LD BC,HEAPEND-HEAP-1 ; Size of heap except first byte LDIR ; Propagate zero to rest of heap -; +; ; Check sound filename (must be *.PT2, *.PT3, or *.MYM) LD A,(FCB+1) ; Get first char of filename CP ' ' ; Compare to blank @@ -179,7 +195,7 @@ SETDLY: CP ' ' ; is blanks JR NZ,HASEXT ; then assume LD A,'P' ; type PT3. - LD (FCB+9),A + LD (FCB+9),A LD A,'T' ; Fill in LD (FCB+10),A ; the file LD A,'3' ; extension @@ -214,13 +230,15 @@ CHKMYM LD A,(FCB+9) ; Extension char 1 _SET LD A,C ; Get file type value LD (FILTYP),A ; Save file type value ; + CALL CLI_ABRT_UNSUPPFILTYP + ; Load sound file _LD0 LD C,15 ; CPM Open File function LD DE,FCB ; FCB CALL BDOS ; Do it INC A ; Test for error $FF JP Z,ERRFIL ; Handle file error -; +; LD A,(FILTYP) ; Get file type LD HL,MDLADDR ; Assume load address LD (DMA),HL ; ... for PTx files @@ -240,22 +258,22 @@ _LD LD HL,(DMA) ; Get load address POP DE ; Restore current DMA to DE LD C,26 ; CPM Set DMA function CALL BDOS ; Read next 128 bytes -; +; LD C,20 ; CPM Read Sequential function LD DE,FCB ; FCB CALL BDOS ; Read next 128 bytes OR A ; Set flags to check EOF JR NZ,_LDX ; Non-zero is EOF JR Z,_LD ; Load loop -; +; _LDX LD C,16 ; CPM Close File function LD DE,FCB ; FCB CALL BDOS ; Do it -; - ; Play loop - CALL CRLF2 ; Formatting - LD DE,MSGPLY ; Playing message - CALL PRTSTR ; Print message +; + ; Play loop +; CALL CRLF2 ; Formatting +; LD DE,MSGPLY ; Playing message +; CALL PRTSTR ; Print message ;CALL CRLF2 ; Formatting ;CALL SLOWCPU LD A,(FILTYP) ; Get file type @@ -278,7 +296,29 @@ GOPT3 LD A,0 ; SETUP value to PT3 sound files LD DE,185 ; Avg TS / quark = 7400, so 185 delay loops JR GOPTX ; Play PTx file -GOPTX LD HL,(QDLY) ; Get basic quark delay +GOPTX + CALL CRLF2 + LD DE, MSGSONGNAME ; Print song name message + CALL PRTSTR + LD DE, MDLADDR + $1E ; Print 32 character long song name from module + LD B, $20 +GOPTX1 LD A,(DE) + CALL PRTCHR + INC DE + DJNZ GOPTX1 + CALL CRLF + LD DE, MSGARTIST ; Print "by" message + CALL PRTSTR + LD DE, MDLADDR + $42 ; Print 32 character long composer/artist from module + LD B, $20 +GOPTX2 LD A,(DE) + CALL PRTCHR + INC DE + DJNZ GOPTX2 + CALL CRLF2 ; Formatting + LD DE,MSGPLY ; Playing message + CALL PRTSTR ; Print message + LD HL,(QDLY) ; Get basic quark delay OR A ; Clear carry SBC HL,DE ; Adjust for file type LD (QDLY),HL ; Save updated quark delay factor @@ -296,7 +336,11 @@ PTXLP CALL START+5 ; Play one quark CALL WAITQ ; Wait one quark period JR PTXLP ; Loop for next quark ; -gomym ld hl,(QDLY) ; Get basic quark delay +gomym + CALL CRLF2 ; Formatting + LD DE,MSGPLY ; Playing message + CALL PRTSTR ; Print message + ld hl,(QDLY) ; Get basic quark delay or a ; Clear carry ld de,125 ; Avg TS / quark = ~5000, so 125 delay loops sbc hl,de ; Adjust for file type @@ -319,7 +363,7 @@ waitvb call WAITQ ld (played),a ;call PRTDOT jr mymlp -; +; EXIT CALL START+8 ; Mute audio ;CALL NORMCPU ;CALL CRLF2 ; Formatting @@ -327,43 +371,12 @@ EXIT CALL START+8 ; Mute audio CALL PRTSTR ; Print message CALL CRLF ; Formatting JP 0 ; Exit the easy way -; -; Wait for quark play time. Can use hardware timer if -; supported by hardware or simple delay loop otherwise. -; Delay loop requires QDLY to be pre-set to to achieve -; optimal 20ms wait time. -; -WAITQ LD A,(WMOD) ; Get delay mode - OR A ; Set flags - JR Z,DLY ; Delay mode -; - ; Timer loop - CALL TIM2 ; Read timer LSB into A - LD C,A ; Init prev value -TIM1 PUSH BC ; Save prev value - CALL TIM2 ; Read timer LSB into A - POP BC ; Recover prev value - CP C ; Compare to prev - RET NZ ; Done if changed - JR TIM1 ; Else, loop -; -TIM2 LD B,$F8 ; BIOS SYSGET function - LD C,$D0 ; TIMER sub-function - RST 08 ; Call BIOS - LD A,L ; MSB to A - RET ; Return to loop -; - ; Delay spin loop (40 tstates per loop) -DLY LD BC,(QDLY) ; Load quark delay factor -DLY1 DEC BC ; [6] - NOP ; [4] - NOP ; [4] - NOP ; [4] - NOP ; [4] - LD A,B ; [4] - OR C ; [4] - JP NZ,DLY1 ; [10] - RET + +#include "timing.inc" +#include "strings.inc" +#include "cli.inc" +#include "printing.inc" + ; ; Get a keystroke from CPM ; @@ -410,7 +423,7 @@ IDBIO1: LD B,BF_SYSVER ; HBIOS: VER function LD C,0 ; required reserved value RST 08 ; DE := version, L := platform id -; +; LD A,1 ; HBIOS BIOS id = 1 RET ; and done ; @@ -421,43 +434,44 @@ IDBIO2: ; ; ; -SLOWCPU: - LD A,(Z180) ; Z180 base I/O port - CP $FF ; Check for no value - RET Z ; Bail out if no value - ADD A,$1E ; Apply offset of CMR register - LD C,A ; And put it in C - LD B,0 ; MSB for 16-bit I/O - IN A,(C) ; Get current value - LD (CMRSAV),A ; Save it to restore later - XOR A ; Go slow - OUT (C),A ; And update CMR - INC C ; Now point to CCR register - IN A,(C) ; Get current value - LD (CCRSAV),A ; Save it to restore later - XOR A ; Go slow - OUT (C),A ; And update CCR - RET -; -; -; -NORMCPU: - LD A,(Z180) ; Z180 base I/O port - CP $FF ; Check for no value - RET Z ; Bail out if no value - ADD A,$1E ; Apply offset of CMR register - LD C,A ; And put it in C - LD B,0 ; MSB for 16-bit I/O - LD A,(CMRSAV) ; Get original CMR value - OUT (C),A ; And update CMR - INC C ; Now point to CCR register - LD A,(CCRSAV) ; Get original CCR value - OUT (C),A ; And update CCR - RET -; -; +;SLOWCPU: +; LD A,(Z180) ; Z180 base I/O port +; CP $FF ; Check for no value +; RET Z ; Bail out if no value +; ADD A,$1E ; Apply offset of CMR register +; LD C,A ; And put it in C +; LD B,0 ; MSB for 16-bit I/O +; IN A,(C) ; Get current value +; LD (CMRSAV),A ; Save it to restore later +; XOR A ; Go slow +; OUT (C),A ; And update CMR +; INC C ; Now point to CCR register +; IN A,(C) ; Get current value +; LD (CCRSAV),A ; Save it to restore later +; XOR A ; Go slow +; OUT (C),A ; And update CCR +; RET +; +; +; +;NORMCPU: +; LD A,(Z180) ; Z180 base I/O port +; CP $FF ; Check for no value +; RET Z ; Bail out if no value +; ADD A,$1E ; Apply offset of CMR register +; LD C,A ; And put it in C +; LD B,0 ; MSB for 16-bit I/O +; LD A,(CMRSAV) ; Get original CMR value +; OUT (C),A ; And update CMR +; INC C ; Now point to CCR register +; LD A,(CCRSAV) ; Get original CCR value +; OUT (C),A ; And update CCR +; RET +; +; SLOW DOWN I/O FOR FAST CPU'S ; SLOWIO: +#IF (CPUFAMZ180) LD A,(Z180) ; Z180 base I/O port CP $FF ; Check for no value RET Z ; Bail out if no value @@ -468,11 +482,17 @@ SLOWIO: LD (DCSAV),A ; Save it to restore later OR %00110000 ; Force slow operation (I/O W/S=3) OUT (C),A ; And update DCNTL +#ENDIF +#IF (SBCV2004) + LD A,8 ; sbc-v2-004 change to + OUT (112),A ; half clock speed +#ENDIF RET ; -; +; RESTORE I/O SPEED FOR FAST CPU'S ; NORMIO: +#IF (CPUFAMZ180) LD A,(Z180) ; Z180 base I/O port CP $FF ; Check for no value RET Z ; Bail out if no value @@ -481,190 +501,11 @@ NORMIO: LD B,0 ; MSB for 16-bit I/O LD A,(DCSAV) ; Get saved DCNTL value OUT (C),A ; And restore it - 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 -; -PRTDOT: -; - ; shortcut to print a dot preserving all regs - PUSH AF ; save af - LD A,'.' ; load dot char - CALL PRTCHR ; print it - POP AF ; restore af - RET ; done -; -PRTCR: -; - ; shortcut to print a dot preserving all regs - PUSH AF ; save af - LD A,13 ; load CR value - CALL PRTCHR ; print it - POP AF ; restore af - RET ; done -; -; Print a zero terminated string at (DE) without destroying any registers -; -PRTSTR: - PUSH DE -; -PRTSTR1: - LD A,(DE) ; get next char - OR A - JR Z,PRTSTR2 - CALL PRTCHR - INC DE - JR PRTSTR1 -; -PRTSTR2: - POP DE ; restore registers - 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 -; -; print the hex word value in bc -; -PRTHEXWORD: - PUSH AF - LD A,B - CALL PRTHEX - LD A,C - CALL PRTHEX - 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 ; 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 -; -; Print value of A or HL in decimal with leading zero suppression -; Use prtdecb for A or prtdecw for HL -; -PRTDECB: - PUSH HL - LD H,0 - LD L,A - CALL PRTDECW ; print it - POP HL - RET -; -PRTDECW: - PUSH AF - PUSH BC - PUSH DE - PUSH HL - CALL PRTDEC0 - POP HL - POP DE - POP BC - POP AF - RET -; -PRTDEC0: - 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 -PRTDEC1: - LD A,'0' - 1 -PRTDEC2: - INC A - ADD HL,BC - JR C,PRTDEC2 - SBC HL,BC - CP E - RET Z - LD E,0 - CALL PRTCHR - RET -; -; Start a new line -; -CRLF2: - CALL CRLF ; two of them -CRLF: - PUSH AF ; preserve AF - LD A,13 ; - CALL PRTCHR ; print it - LD A,10 ; - CALL PRTCHR ; print it - POP AF ; restore AF - RET -; -; ADD HL,A -; -; A REGISTER IS DESTROYED! -; -ADDHLA: - ADD A,L - LD L,A - RET NC - INC H +#ENDIF +#IF (SBCV2004) + LD A,0 ; sbc-v2-004 change to + OUT (112),A ; normal clock speed +#ENDIF RET ; ERRBIO: ; Invalid BIOS or version @@ -712,34 +553,46 @@ CFGSIZ .EQU 8 CFGTBL: ; PLT RSEL RDAT RIN Z180 ACR ; DESC .DB $01, $9A, $9B, $9A, $FF, $9C ; SBC W/ SCG - .DW HWSTR_SCG -; + .DW HWSTR_SCG +; .DB $04, $9C, $9D, $9C, $40, $FF ; N8 W/ ONBOARD PSG - .DW HWSTR_N8 -; + .DW HWSTR_N8 +; .DB $05, $9A, $9B, $9A, $40, $9C ; MK4 W/ SCG - .DW HWSTR_SCG -; + .DW HWSTR_SCG +; .DB $07, $D8, $D0, $D8, $FF, $FF ; RCZ80 W/ RC SOUND MODULE (EB) - .DW HWSTR_RCEB -; + .DW HWSTR_RCEB +; + .DB $07, $A0, $A1, $A2, $FF, $FF ; RCZ80 W/ RC SOUND MODULE (EB Rev 6) + .DW HWSTR_RCEB6 +; .DB $07, $D1, $D0, $D0, $FF, $FF ; RCZ80 W/ RC SOUND MODULE (MF) .DW HWSTR_RCMF -; +; .DB $08, $68, $60, $68, $C0, $FF ; RCZ180 W/ RC SOUND MODULE (EB) - .DW HWSTR_RCEB -; + .DW HWSTR_RCEB +; + .DB $08, $A0, $A1, $A2, $C0, $FF ; RCZ180 W/ RC SOUND MODULE (EB Rev 6) + .DW HWSTR_RCEB6 +; .DB $08, $61, $60, $60, $C0, $FF ; RCZ180 W/ RC SOUND MODULE (MF) .DW HWSTR_RCMF ; .DB $09, $D8, $D0, $D8, $FF, $FF ; EZZ80 W/ RC SOUND MODULE (EB) - .DW HWSTR_RCEB + .DW HWSTR_RCEB +; + .DB $09, $A0, $A1, $A2, $FF, $FF ; EZZ80 W/ RC SOUND MODULE (EB Rev 6) + .DW HWSTR_RCEB6 ; - .DB $09, $D1, $D0, $D0, $FF, $FF ; EZZ80 W/ RC SOUND MODULE (EB) + .DB $09, $D1, $D0, $D0, $FF, $FF ; EZZ80 W/ RC SOUND MODULE (MF) .DW HWSTR_RCMF ; .DB $0A, $68, $60, $68, $C0, $FF ; SCZ180 W/ RC SOUND MODULE (EB) .DW HWSTR_RCEB +; + .DB $0A, $A0, $A1, $A2, $C0, $FF ; SCZ180 W/ RC SOUND MODULE (EB Rev 6) + .DW HWSTR_RCEB6 ; .DB $0A, $61, $60, $60, $C0, $FF ; SCZ180 W/ RC SOUND MODULE (MF) .DW HWSTR_RCMF @@ -765,15 +618,17 @@ CMRSAV .DB 0 ; for saving original Z180 CMR value ; DMA .DW 0 ; Working DMA FILTYP .DB 0 ; Sound file type (TYPPT2, TYPPT3, TYPMYM) -; -TMP .DB 0 ; work around use of undocumented Z80 ; - -MSGBAN .DB "Tune Player for RomWBW v2.5, 29-Mar-2020",0 +TMP .DB 0 ; work around use of undocumented Z80 + +HBIOSMD .DB 0 ; NON-ZERO IF USING HBIOS SOUND DRIVER, ZERO OTHERWISE +OCTAVEADJ .DB 0 ; AMOUNT TO ADJUST OCTAVE UP OR DOWN + +MSGBAN .DB "Tune Player for RomWBW v3.2, 03-Sep-2020",0 MSGUSE .DB "Copyright (C) 2020, Wayne Warthen, GNU GPL v3",13,10 .DB "PTxPlayer Copyright (C) 2004-2007 S.V.Bulba",13,10 .DB "MYMPlay by Marq/Lieves!Tuore",13,10,13,10 - .DB "Usage: TUNE .[PT2|PT3|MYM]",0 + .DB "Usage: TUNE .[PT2|PT3|MYM] [--hbios] [+tn|-tn]",0 MSGBIO .DB "Incompatible BIOS or version, " .DB "HBIOS v", '0' + RMJ, ".", '0' + RMN, " required",0 MSGPLT .DB "Hardware error, system not supported!",0 @@ -785,11 +640,18 @@ MSGTIM .DB ", timer mode",0 MSGDLY .DB ", delay mode",0 MSGPLY .DB "Playing...",0 MSGEND .DB " Done",0 +MSGERR .DB "App Error", 0 ; HWSTR_SCG .DB "SCG ECB Board",0 HWSTR_N8 .DB "N8 Onboard Sound",0 HWSTR_RCEB .DB "RC2014 Sound Module (EB)",0 +HWSTR_RCEB6 .DB "RC2014 Sound Module (EBv6)",0 HWSTR_RCMF .DB "RC2014 Sound Module (MF)",0 + +MSGUNSUP .db "MYM files not supported yet!\r\n", 0 + +MSGSONGNAME .DB "Song name: ", 0 +MSGARTIST .DB "by: ", 0 ; ;=============================================================================== ; PTx Player Routines @@ -799,23 +661,6 @@ HWSTR_RCMF .DB "RC2014 Sound Module (MF)",0 ;(c)2004-2007 S.V.Bulba ;http://bulba.untergrund.net (http://bulba.at.kz) -;Release number -;Release .EQU "1" -#DEFINE Release "1" - -;Conditional assembly -;1) Version of ROUT (ZX or MSX standards) -ZX .EQU 0 -MSX .EQU 0 -WBW .EQU 1 -;2) Current position counter at (START+11) -CurPosCounter .EQU 0 -;3) Allow channels allocation bits at (START+10) -ACBBAC .EQU 0 -;4) Allow loop checking and disabling -LoopChecker .EQU 1 -;5) Insert official identificator -Id .EQU 1 ;Features ;-------- @@ -843,7 +688,7 @@ Id .EQU 1 ;into RAM or INIT subprogram was not called before. ;Call MUTE or INIT one more time to mute sound after stopping -;playing +;playing ;ORG $C000 ;Test codes (commented) @@ -932,7 +777,9 @@ CurPos .DB 0 ;for visualization only (i.e. no need for playing) ;Identifier .IF Id - .DB "=Uni PT2 and PT3 Player r.",Release,"=" + .DB "=Uni PT2 and PT3 Player r." + .DB Release + .DB "=" .ENDIF .IF LoopChecker @@ -1128,7 +975,7 @@ TP_2 LD A,H #IF CurPosCounter LD (CurPos),A #ENDIF - + #ENDIF LD HL,VARS @@ -1441,7 +1288,7 @@ PD_VOL RRCA RRCA LD (IX-12+Volume),A JR PD_LP2 - + PD_EOff LD (IX-12+Env_En),A LD (IX-12+PsInOr),A JR PD_LP2 @@ -1660,7 +1507,7 @@ C_DELAY LD A,(BC) INC BC LD (Delay),A RET - + SETENV LD (IX-12+Env_En),E LD (AYREGS+EnvTp),A LD A,(BC) @@ -1783,7 +1630,7 @@ CH_SMPS LD (IX+PsInSm),A ;Convert PT2 sample to PT3 ;PT2 PT3 SamCnv POP HL ;BIT 2,C JR e_ - POP HL + POP HL LD H,B JR NZ,$+8 EX DE,HL @@ -2130,14 +1977,14 @@ RxCA2 OR E ABC #ENDIF -#IF ZX +#IF _ZX XOR A LD DE,$FFBF LD BC,$FFFD LD HL,AYREGS LOUT OUT (C),A LD B,E - OUTI + OUTI LD B,D INC A CP 13 @@ -2151,14 +1998,14 @@ LOUT OUT (C),A RET #ENDIF -#IF MSX +#IF _MSX ;MSX version of ROUT (c)Dioniso XOR A LD C,$A0 LD HL,AYREGS LOUT OUT (C),A INC C - OUTI + OUTI DEC C INC A CP 13 @@ -2172,32 +2019,104 @@ LOUT OUT (C),A RET #ENDIF -#IF WBW +#IF _WBW + ISHBIOS + JR NZ, PLAYVIAHBIOS + DI - CALL SLOWIO - LD DE,(PORTS) ; D := RDAT, E := RSEL - XOR A ; start with reg 0 - LD C,E ; point to address port - LD HL,AYREGS ; start of value list -LOUT OUT (C),A ; select register - LD C,D ; point to data port - OUTI ; write (HL) to data port, bump HL - LD C,E ; point to address port - INC A ; next register - CP 13 ; reg 13? - JR NZ,LOUT ; if not, loop - OUT (C),A ; select register 13 - LD A,(HL) ; get value for register 13 - AND A ; set flags - JP M,LOUT2 ; if bit 7 set, return w/o writing value - LD C,D ; select data port - OUT (C),A ; write value to register 13 -LOUT2 - CALL NORMIO + CALL SLOWIO + LD DE, (PORTS) ; D := RDAT, E := RSEL + XOR A ; START WITH REG 0 + LD C, E ; POINT TO ADDRESS PORT + LD HL, AYREGS ; START OF VALUE LIST +LOUT OUT (C), A ; SELECT REGISTER + LD C, D ; POINT TO DATA PORT + OUTI ; WRITE (HL) TO DATA PORT, BUMP HL + LD C, E ; POINT TO ADDRESS PORT + INC A ; NEXT REGISTER + CP 13 ; REG 13? + JR NZ, LOUT ; IF NOT, LOOP + OUT (C), A ; SELECT REGISTER 13 + LD A, (HL) ; GET VALUE FOR REGISTER 13 + AND A ; SET FLAGS + JP M, LOUT2 ; IF BIT 7 SET, RETURN W/O WRITING VALUE + LD C, D ; SELECT DATA PORT + OUT (C), A ; WRITE VALUE TO REGISTER 13 +LOUT2 CALL NORMIO EI - RET ; And done + RET ; AND DONE + +PLAYVIAHBIOS: +; CHANNEL 0 + LD HL, AYREGS + AmplA + LD DE, AYREGS + TonA + LD B, 0 + CALL PLAYNOTE +; +; CHANNEL 1 + LD HL, AYREGS + AmplB + LD DE, AYREGS + TonB + LD B, 1 + CALL PLAYNOTE + +; CHANNEL 2 + LD HL, AYREGS + AmplC + LD DE, AYREGS + TonC + LD B, 2 + JP PLAYNOTE + +PLAYNOTE: + PUSH BC ; CHANNEL IN B + PUSH DE ; PERIOD ADDR IN DE + + LD A, (HL) + ADD A,A ; GET 4-BIT + ADD A,A ; VOLUME 0-15 + ADD A,A ; AND CONVERT + ADD A,A ; TO HBIOS + LD L, A ; RANGE 0-255 + LD BC, (BF_SNDVOL*256)+0 ; SET VOLUME + RST 08 +; + POP HL ; RESTORE PERIOD ADDR + LD A, (HL) ; DEVICE 0 + INC HL + LD H, (HL) + LD L, A + LD A, H ; GET 12-BIT ONE PERIOD + AND $0F ; MASK OFF HIGH + LD H, A ; NIBBLE + + LD A, (OCTAVEADJ) + OR A + JR Z, PLAYNOTE3 ; NO OCTAVE ADJUSTMENT + BIT 7, A + JR Z, PLAYNOTE2 ; OCTAVE DOWN ADJUSTMENT + +PLAYNOTE1: + ADD HL, HL ; MULTIPLE BY 2 FOR EACH OCTAVE + INC A + JR NZ, PLAYNOTE1 + JR PLAYNOTE3 + +PLAYNOTE2: + SRL H ; DIVIDE BY 2 FOR EACH OCTAVE + RR L + DEC A + JR NZ, PLAYNOTE2 + +PLAYNOTE3 + LD BC, (BF_SNDPRD*256)+0 ; SET PERIOD + RST 08 +; + POP DE ; RESTORE CHANNEL IN D (FROM B) + LD BC, (BF_SNDPLAY*256)+0 ; PLAY + RST 08 + + RET + #ENDIF - + #IF ACBBAC CHTABLE .EQU $-4 .DB 4,5,15,%001001,0,7,7,%100100 @@ -2518,7 +2437,7 @@ endext: ld (dest1),ix ld bc,(rows) or a sbc hl,bc - + ; jr c,noend ; If rows>played rows then exit ; exx ; Otherwise restart ; ld e,1 @@ -2553,9 +2472,16 @@ zero: djnz onebit ret ; *** Update PSG registers -upsg: ld a,(WMOD) ; if WMOD = 1, CPU is z180 +upsg: + ISHBIOS + JR Z, upsg0 + ERRWITHMSG(MSGERR) + +upsg0: + ld a,(WMOD) ; if WMOD = 1, CPU is z180 or a ; set flags jr z,upsg1 ; skip z180 stuff + di call SLOWIO @@ -2563,29 +2489,29 @@ upsg1: ld hl,(psource) ld de,(PORTS) ; E := RSEL, D := RDAT xor a -psglp: ld c,e ; C := RSEL - out (c),a ; Select register - ld c,d ; C := RDAT +psglp: ld c, e ; C := RSEL + out (c), a ; Select register + ld c, d ; C := RDAT outi ; Set register value - inc a ; Next register - ld bc,(3*FRAG)-1 ; Bytes to skip before next reg-1 - add hl,bc ; Update HL - cp REGS-1 ; Check for next to last register? - jr nz,psglp ; If not, loop + inc a ; Next register + + ld bc, (3 * FRAG) - 1 ; Bytes to skip before next reg-1 + add hl, bc ; Update HL + cp REGS-1 ; Check for next to last register? + jr nz,psglp ; If not, loop - ld a,$FF ; Prepare to check for $FF value + ld a, $FF ; Prepare to check for $FF value cp (hl) ; If last reg (13) is $FF - jr z,notrig ; ... then don't output - ld a,13 ; Register 13 - ld c,e ; C := RSEL - out (c),a ; Select register - ld c,d ; C := RDAT + jr z, notrig ; ... then don't output + ld a, 13 ; Register 13 + ld c, e ; C := RSEL + out (c), a ; Select register + ld c, d ; C := RDAT outi ; Set register value -notrig: ld hl,(psource) +notrig: ld hl,(psource) inc hl ld (psource),hl - ld a,(played) or a jr z,endint @@ -2593,9 +2519,10 @@ notrig: ld hl,(psource) ld (played),a endint: call NORMIO - ei + ei ret ; And done ; + ; *** Program data played .db 0 ; VBI counter dest1 .dw 0 ; Uncompress destination 1 diff --git a/Source/Apps/Tune/cli.inc b/Source/Apps/Tune/cli.inc new file mode 100644 index 00000000..fc901068 --- /dev/null +++ b/Source/Apps/Tune/cli.inc @@ -0,0 +1,86 @@ + +CLI_ABRT_IF_OPT_FIRST: + LD A, (FCB+1) + CP '-' ; OPTION FIRST OR - MISSING FILENAME? + JP Z, ERRCMD ; SHOW USAGE + RET + +CLI_HAVE_HBIOS_SWITCH: + LD HL, CLIARGS ; TEST FOR --HBIOS ON COMMAND LINE + LD DE, HBIOSOPT + CALL STRINDEX + JR NZ, CLI_HAVE_HBIOS_SWITCH1 + OR $FF ; MATCHED --HBIOS + LD (HBIOSMD), A + LD BC,(BF_SYSGET*256)+BF_SND + RST 08 ; CHECK WE HAVE + XOR A ; AT LEAST ONE + CP E ; SOUND DEVICE + RET NZ + JP ERRHW +CLI_HAVE_HBIOS_SWITCH1 ; NOT MATCHED --HBIOS + XOR A + LD (HBIOSMD), A + RET + +CLI_ABRT_UNSUPPFILTYP: + PUSH AF + ISHBIOS + JR Z, CLI_ABRT_UNSUPPFILTYP1 + POP AF + CP TYPMYM + RET NZ + ERRWITHMSG(MSGUNSUP) ; EXIT WITH UNSUPPORTED FILE TYPE MESSAGE + +CLI_ABRT_UNSUPPFILTYP1: + POP AF + RET + +CLI_OCTAVE_ADJST: ; SEARCH FOR OCTAVE ADJUSTMENT SWITCH (-n or +n) + LD HL, CLIARGS ; TEST FOR --HBIOS ON COMMAND LINE + LD DE, DOWN1 + CALL STRINDEX + JR NZ, CLI_OCTAVE_ADJST1 + + LD A, -1 + JR CLI_OCTAVE_ADJST5 + +CLI_OCTAVE_ADJST1: + LD HL, CLIARGS ; TEST FOR --HBIOS ON COMMAND LINE + LD DE, DOWN2 + CALL STRINDEX + JR NZ, CLI_OCTAVE_ADJST2 + + LD A, -2 + JR CLI_OCTAVE_ADJST5 + +CLI_OCTAVE_ADJST2: + LD HL, CLIARGS ; TEST FOR --HBIOS ON COMMAND LINE + LD DE, UP1 + CALL STRINDEX + JR NZ, CLI_OCTAVE_ADJST3 + + LD A, 1 + JR CLI_OCTAVE_ADJST5 + +CLI_OCTAVE_ADJST3: + LD HL, CLIARGS ; TEST FOR --HBIOS ON COMMAND LINE + LD DE, UP2 + CALL STRINDEX + JR NZ, CLI_OCTAVE_ADJST4 + + LD A, 2 + JR CLI_OCTAVE_ADJST5 + +CLI_OCTAVE_ADJST4: + LD A, 0 + +CLI_OCTAVE_ADJST5: + LD (OCTAVEADJ), A + RET + +HBIOSOPT: .DB "--HBIOS", 0 +DOWN1 .DB "-t1", 0 ; DOWN AN OCTAVE +DOWN2 .DB "-t2", 0 ; DOWN TWO OCTAVE +UP1 .DB "+t1", 0 ; UP AN OCTAVE +UP2 .DB "+t2", 0 ; UP TWO OCTAVE diff --git a/Source/Apps/Tune/cpm.inc b/Source/Apps/Tune/cpm.inc new file mode 100644 index 00000000..a3c84af9 --- /dev/null +++ b/Source/Apps/Tune/cpm.inc @@ -0,0 +1,4 @@ +CLIARGS .EQU $81 +RESTART .EQU $0000 ; CP/M restart vector +BDOS .EQU $0005 ; BDOS invocation vector +FCB .EQU $5C ; Location of default FCB diff --git a/Source/Apps/Tune/hbios.inc b/Source/Apps/Tune/hbios.inc new file mode 100644 index 00000000..7a2ffea1 --- /dev/null +++ b/Source/Apps/Tune/hbios.inc @@ -0,0 +1,15 @@ +IDENT .EQU $FFFE ; loc of RomWBW HBIOS ident ptr +; +RMJ .EQU 3 ; intended CBIOS version - major +RMN .EQU 1 ; intended CBIOS version - minor +; +BF_SYSVER .EQU $F1 ; BIOS: VER function +BF_SYSGET .EQU $F8 ; HBIOS: SYSGET function +; +BF_SND .EQU $50 +BF_SNDRESET .EQU BF_SND + 0 ; RESET SOUND SYSTEM +BF_SNDVOL .EQU BF_SND + 1 ; REQUEST SOUND VOL - L CONTAINS VOLUME (255 MAX, 0 SILENT) - SCALED AS REQUIRED BY DRIVER (EG: MAPS TO JUST 4 BIT RESOLUTION FOR SN76489) +BF_SNDPRD .EQU BF_SND + 2 ; REQUEST SOUND PERIOD - HL CONTAINS DRIVER SPECIFIC VALUE +BF_SNDNOTE .EQU BF_SND + 3 ; REQUEST NOTE - L CONTAINS NOTE - EACH VALUE IS QUARTER NOTE +BF_SNDPLAY .EQU BF_SND + 4 ; INITIATE THE REQUESTED SOUND COMMAND +BF_SNDQUERY .EQU BF_SND + 5 ; E IS SUBFUNCTION diff --git a/Source/Apps/Tune/printing.inc b/Source/Apps/Tune/printing.inc new file mode 100644 index 00000000..6d118ea2 --- /dev/null +++ b/Source/Apps/Tune/printing.inc @@ -0,0 +1,175 @@ +; +; 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 +; +PRTDOT: +; + ; shortcut to print a dot preserving all regs + PUSH AF ; save af + LD A,'.' ; load dot char + CALL PRTCHR ; print it + POP AF ; restore af + RET ; done +; +PRTCR: +; + ; shortcut to print a carriage return preserving all regs + PUSH AF ; save af + LD A,13 ; load CR value + CALL PRTCHR ; print it + POP AF ; restore af + RET ; done +; +; Print a zero terminated string at (DE) without destroying any registers +; +PRTSTR: + PUSH DE +; +PRTSTR1: + LD A,(DE) ; get next char + OR A + JR Z,PRTSTR2 + CALL PRTCHR + INC DE + JR PRTSTR1 +; +PRTSTR2: + POP DE ; restore registers + 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 +; +; print the hex word value in bc +; +PRTHEXWORD: + PUSH AF + LD A,B + CALL PRTHEX + LD A,C + CALL PRTHEX + 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 ; 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 + +; +; Print value of A or HL in decimal with leading zero suppression +; Use prtdecb for A or prtdecw for HL +; +PRTDECB: + PUSH HL + LD H,0 + LD L,A + CALL PRTDECW ; print it + POP HL + RET +; +PRTDECW: + PUSH AF + PUSH BC + PUSH DE + PUSH HL + CALL PRTDEC0 + POP HL + POP DE + POP BC + POP AF + RET +; +PRTDEC0: + 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 +PRTDEC1: + LD A,'0' - 1 +PRTDEC2: + INC A + ADD HL,BC + JR C,PRTDEC2 + SBC HL,BC + CP E + RET Z + LD E,0 + CALL PRTCHR + RET +; +; Start a new line +; +CRLF2: + CALL CRLF ; two of them +CRLF: + PUSH AF ; preserve AF + LD A,13 ; + CALL PRTCHR ; print it + LD A,10 ; + CALL PRTCHR ; print it + POP AF ; restore AF + RET diff --git a/Source/Apps/Tune/strings.inc b/Source/Apps/Tune/strings.inc new file mode 100644 index 00000000..5df10276 --- /dev/null +++ b/Source/Apps/Tune/strings.inc @@ -0,0 +1,39 @@ +STRINDEX: ; SEARCH FOR STRING AT DE WITHIN STRING AT HL + + LD B, 0 + LD C, 0 + +TRYNEXT: + PUSH HL + PUSH DE + CALL STRCMP + POP DE + POP HL + RET Z + + INC HL + INC BC + LD A, (HL) + OR A + JR NZ, TRYNEXT + + OR $FF ; RETURN NZ + RET + +STRCMP: ; COMPARE STRING AT HL WITH DE - RETURN Z IF LIKE + LD A, (DE) + OR A + RET Z + + LD B, A + LD A, (HL) + OR A + JR NZ, STRCMP1 + OR $FF ; END OF STRING HL - SO NOT FOUND + RET +STRCMP1 + CP B + RET NZ + INC HL + INC DE + JR STRCMP diff --git a/Source/Apps/Tune/timing.inc b/Source/Apps/Tune/timing.inc new file mode 100644 index 00000000..857e4d2c --- /dev/null +++ b/Source/Apps/Tune/timing.inc @@ -0,0 +1,60 @@ + +; +; Wait for quark play time. Can use hardware timer if +; supported by hardware or simple delay loop otherwise. +; Delay loop requires QDLY to be pre-set to to achieve +; optimal 20ms wait time. +; +WAITQ LD A,(WMOD) ; Get delay mode + OR A ; Set flags + JR Z,DLY ; Delay mode +; + ; Timer loop + CALL TIM2 ; Read timer LSB into A + LD C,A ; Init prev value +TIM1 PUSH BC ; Save prev value + CALL TIM2 ; Read timer LSB into A + POP BC ; Recover prev value + CP C ; Compare to prev + RET NZ ; Done if changed + JR TIM1 ; Else, loop +; +TIM2 LD B,$F8 ; BIOS SYSGET function + LD C,$D0 ; TIMER sub-function + RST 08 ; Call BIOS + LD A,L ; MSB to A + RET ; Return to loop +; + ; Delay spin loop (40 tstates per loop) +DLY LD BC,(QDLY) ; Load quark delay factor +DLY1 DEC BC ; [6] + NOP ; [4] + NOP ; [4] + NOP ; [4] + NOP ; [4] + LD A,B ; [4] + OR C ; [4] + JP NZ,DLY1 ; [10] + RET + +; +; Test for timer running to determine if it can be used for delay +; Return string message in DE +; Assigned (WMOD) with 0 if no hardware time, 1 if hardware timer found +; +PROBETIMER: + LD B,BF_SYSGET ; HBIOS: GET function + LD C,$D0 ; TIMER subfunction + RST 08 ; DE:HL := current tick count + LD A,L ; DE:HL == 0? + OR H + OR E + OR D + LD A,0 ; Assume no timer + LD DE,MSGDLY ; Delay mode msg + JR Z,SETDLY ; If tick count is zero, no timer active + LD A,$FF ; Value for timer active + LD DE,MSGTIM ; Timer mode msg +SETDLY: + LD (WMOD),A ; Save wait mode + RET diff --git a/Source/Apps/Tune/tune.inc b/Source/Apps/Tune/tune.inc new file mode 100644 index 00000000..3db0e0e9 --- /dev/null +++ b/Source/Apps/Tune/tune.inc @@ -0,0 +1,4 @@ +#DEFINE ISHBIOS LD A, (HBIOSMD) \ OR A +#DEFINE PRTSTRDE(X) LD DE, X \ CALL PRTSTR +#DEFINE PRTCRLF CALL CRLF +#DEFINE ERRWITHMSG(X) LD DE, X \ JP ERR diff --git a/Source/Apps/XM/Build.cmd b/Source/Apps/XM/Build.cmd index 4fbbae00..6105dac4 100644 --- a/Source/Apps/XM/Build.cmd +++ b/Source/Apps/XM/Build.cmd @@ -10,13 +10,21 @@ set ZXLIBDIR=%TOOLS%\cpm\lib\ set ZXINCDIR=%TOOLS%\cpm\include\ zx mac xmdm125.asm $PO + zx slr180 -xmhb/HF -rem zx slr180 -xmuf/HF zx mload25 XM=xmdm125,xmhb + +rem zx slr180 -xmuf/HF rem zx mload25 XMUF=xmdm125,xmuf +zx slr180 -xmhb_old/HF +zx mload25 XMOLD=xmdm125,xmhb_old + rem set PROMPT=[Build] %PROMPT% rem %comspec% copy /Y XM.com ..\..\..\Binary\Apps\ rem copy /Y XMUF.com ..\..\..\Binary\Apps\ +copy /Y XMOLD.com ..\..\..\Binary\Apps\ + +rem pause \ No newline at end of file diff --git a/Source/Apps/XM/Makefile b/Source/Apps/XM/Makefile index b16ff7ef..62c4f1e8 100644 --- a/Source/Apps/XM/Makefile +++ b/Source/Apps/XM/Makefile @@ -1,5 +1,5 @@ -#OBJECTS = xm.com xmuf.com -OBJECTS = xm.com +OBJECTS = xm.com xmold.com +#OBJECTS += xmuf.com DEST = ../../../Binary/Apps TOOLS = ../../../Tools OTHERS = *.hex @@ -9,5 +9,8 @@ include $(TOOLS)/Makefile.inc xm.com: xmdm125.hex xmhb.hex $(ZXCC) $(CPM)/MLOAD25 XM=xmdm125,xmhb -#xmuf.com: xmdm125.hex xmuf.hex -# $(ZXCC) $(CPM)/MLOAD25 XMUF=xmdm125,xmuf +xmuf.com: xmdm125.hex xmuf.hex + $(ZXCC) $(CPM)/MLOAD25 XMUF=xmdm125,xmuf + +xmold.com: xmdm125.hex xmhb_old.hex + $(ZXCC) $(CPM)/MLOAD25 XMOLD=xmdm125,xmhb_old diff --git a/Source/Apps/XM/XModem Xfer Anomaly.txt b/Source/Apps/XM/XModem Xfer Anomaly.txt new file mode 100644 index 00000000..45f274bc --- /dev/null +++ b/Source/Apps/XM/XModem Xfer Anomaly.txt @@ -0,0 +1,77 @@ +XModem 12.5 & Tera Term Anomaly Analysis +---------------------------------------- + +Protocol Notes: + +- During protocol startup, the receiver NAKs the sender repeatedly + to let the sender know it can start sending. +- Normally, the receiver sends a NAK character to ask the sender to + resend a packet. +- Prior to receiving the first packet, the receiver may send a "C" + or a "CK" instead of a NAK. This mechanism is used to inform the + sender that the receiver wants to use (C)RC error detection + instead of checksum error detection and optionally 1(K) packet sizes. +- After the first packet exchange, a NAK is always used to + request a packet be resent. + +Anomalous Exchange Description: + +XModem on RomWBW is being used to receive a file being sent +by Tera Term on a Windows PC... + +- XModem is started in receive mode +- User starts process of selecting a file to send on Tera Term +- XModem begins sending "CK" sequences as described above + to wake up the sender +- Tera Term buffers incoming "CK" sequences while user is selecting + a file to send +- User completes file selection +- Tera Term receives the first "CK" which was buffered while user + was selecting a file +- Tera Term correctly receives the first "CK", sets itself to + use CRC and 1K packets, then sends the first packet +- While waiting for Tera Term to send the first packet, XModem + is repeatedly timing out and resending the "CK" sequence +- For each timeout, XModem spends 1 second flushing any incoming + characters from the sender (it assumes it is flushing line garbage). +- IFF the first packet from Tera Term starts to arrive during this + 1 second flushing interval, XModem gobbles up and discards the + first packet sent by Tera Term +- XModem then sends a new "CK" because it is still waiting for the + first packet (having just flushed the actual first packet) +- Tera Term has already switched out of "first packet" mode and will + now only respond to an actual NAK character, so it ignores all of + the CKs send from XModem +- XModem continues to send CKs and Tera Term continues to ignore them + until XModem hits a retry threshold +- When XModem hits the retry threshold, it attempts to switch from + CRC to Checksum assuming the sender was not capable of using + CRCs +- XModem now sends a NAK character because that is what is used for + for first packet NAKing in Checksum mode +- Tera Term sees the NAK and resends the first packet, but appends a + CRC instead of a Checksum because Tera Term is still in CRC mode +- XModem fails the Tera Term first packet resends because it is + looking for a Checksum and Tera Term is appending CRCs. +- XModem eventually gives up. + +Summary of failure: + +If Tera Term happens to start sending the first packet during the +one second "flush" window of XModem, the exchange will fail during +the startup sequence. + +Since the precise start timing of the first packet is dependent on +the time the user takes to select a file, the occurrence of the +failure is essentially random. + +The timeout used by XModem is about 5 seconds followed by the 1 +second line flush. So, there is a 1 in 6 chance that the protocol +will fail to startup successfully. + +Mitigation: + +- Modified the receive timeout recovery to *not* flush the incoming + buffer for one second. Flushing in this scenario makes no sense + anyway because a timeout just occurred meaning no data is being + received. \ No newline at end of file diff --git a/Source/Apps/XM/xmdm125.asm b/Source/Apps/XM/xmdm125.asm index ac881800..e735b618 100644 --- a/Source/Apps/XM/xmdm125.asm +++ b/Source/Apps/XM/xmdm125.asm @@ -71,7 +71,7 @@ STX EQU 02H ; 'Start of header' for 1024 byte blocks ; Conditional equates - change to suit your system, then assemble ; MHZ EQU 10 ; Clock speed, use integer (2,4,5,8, etc.) -SCL EQU 6600 ; WBW: Receive loop timeout scalar +SCL EQU 6600 ; [WBW] Receive loop timeout scalar CPM3 EQU NO ; Yes, if operating in CP/M v3.0 environment STOPBIT EQU NO ; No, if using 1 stop bit, yes if using 2 BYEBDOS EQU NO ; Yes, if using BYE338-up, BYE501-up, or NUBYE @@ -758,7 +758,10 @@ RECVOPT:MVI A,'K' ; First off, default to 1K mode CALL RCVOPC ; Check 4th (or 5th) option ENDIF ; - JMP OPTERR ; If 5th or 6th option, whoops! + ; [WBW] Added to support port number + CALL RCVOPC ; Check 5th (or 6th) option +; + JMP OPTERR ; If 7th or 8th option, whoops! ; RCVOPC: INX H ; Increment pointer to next character MOV A,M ; Get option character HL points to @@ -790,7 +793,7 @@ CHK3RD: CPI 'X' ; Got an "X" for first option? CHK4TH: IF MBFMSG ; Allowing "RM" for message uploads? CPI 'M' ; Got an "M" for message upload? - JNZ CHK5TH ; If not, bad option + JNZ CHK5TH ; Nope, try next STA MSGFLG ; If "M", set MSGFLG MVI A,'P' ; Also, set PRVTFL STA PRVTFL @@ -804,11 +807,21 @@ CHK4TH: CHK5TH: IF NDESC ; Allowing "RN" to skip upload descript? CPI 'N' ; Got an 'N'? - JNZ BADROP ; If nope, is NG.. + JNZ CHK6TH ; Nope, try next STA NDSCFL ; else set flag to skip descript phase RET ENDIF ; +CHK6TH: + ; [WBW] Get target serial port (0-9 supported) + CPI '0' + JC BADROP ; If < 0, out of range + CPI '9' + 1 + JNC BADROP ; If > 9, out of range + SUI '0' ; Make binary + STA PORT + RET +; BADROP: POP PSW ; Restore stack JMP OPTERR ; is bad option ; @@ -817,9 +830,10 @@ BADROP: POP PSW ; Restore stack ; ALLSET: CALL GETCHR CALL GETCHR + LDA PORT ; [WBW] Pass serial port to driver CALL MINIT - STA CPUMHZ ; WBW: Save CPU speed from MINIT - SHLD RCVSCL ; WBW: Save rcv loop scalar from MINIT + STA CPUMHZ ; [WBW] Save CPU speed from MINIT + SHLD RCVSCL ; [WBW] Save rcv loop scalar from MINIT ; ; Jump to appropriate function ; @@ -920,7 +934,8 @@ SKSK2: CALL ILPRT DB 'XMODEM L CAT.LBR CAT.COM send a file from a library' DB CR,LF DB 'XMODEM LK CAT.LBR CAT.COM send in 1k blocks',CR,LF - DB ' The ".LBR" file extension may be omitted',CR,LF,LF + DB ' The ".LBR" file extension may be omitted',CR,LF + DB ' Add "0"-"9" to specify serial port',CR,LF,LF DB 'XMODEM R HELLO.DOC receive a file from you' DB CR,LF DB 'XMODEM RP HELLO.DOC receive in a private area' @@ -939,7 +954,8 @@ SKSK2: CALL ILPRT ; IF NOT LUXMOD DB ' Add "C" for forced checksum ("RC" "RPC")',CR,LF - DB ' Add "X" for forced 128 byte protocol ("RX" "RPX")' + DB ' Add "X" for forced 128 byte protocol ("RX" "RPX")',CR,LF + DB ' Add "0"-"9" to specify serial port' DB CR,LF DB ' "R" switches from CRC to checksum after 5 retries' DB CR,LF,LF @@ -2214,13 +2230,13 @@ ILLDU: CALL ERXIT RCVRECD:XRA A ; Initialize error count to zero STA ERRCT ; -;WBW BEGIN: Be more patient waiting for host to start sending file - LDA FRSTIM ; WBW: Get first time flag - ORA A ; WBW: Set CPU flags - JNZ RCVRPT ; WBW: If not first time, bypass - MVI A,-10 ; WBW: Else increase error limit - STA ERRCT ; WBW: Save error new limit -;WBW END +; [WBW] BEGIN: Be more patient waiting for host to start sending file + LDA FRSTIM ; Get first time flag + ORA A ; Set CPU flags + JNZ RCVRPT ; If not first time, bypass + MVI A,-10 ; Else increase error limit + STA ERRCT ; Save error new limit +; [WBW] END ; RCVRPT: IF CONFUN ; Check for function key? CALL FUNCHK ; Yeah, why not? @@ -2233,7 +2249,7 @@ RCVRPT: IF CONFUN ; Check for function key? ENDIF ; ;MVI B,10-1 ; 10-second timeout - MVI B,5-1 ; WBW: 5-second timeout + MVI B,5-1 ; [WBW] 5-second timeout CALL RECV ; Get any character received JC RCVSTOT ; Timeout ; @@ -2259,7 +2275,7 @@ RCVRPTB:CPI SOH ; 'SOH' for a 128-byte block? RCVSERR:MVI B,1 ; Wait for 1 second CALL RECV ; After last char. received JNC RCVSERR ; Loop until sender done - LDA FRSTIM ; Is it the first time? +RCVSER1:LDA FRSTIM ; Is it the first time? ORA A MVI A,NAK JNZ RCVSER2 ; If not first time, send NAK @@ -2320,7 +2336,9 @@ DELFILE:LXI D,FCB ; Point to file ; ; Timed out on receive ; -RCVSTOT:JMP RCVSERR ; Bump error count, etc. +;RCVSTOT:JMP RCVSERR ; Bump error count, etc. +; [WBW] Bypass line flush if error is timeout +RCVSTOT:JMP RCVSER1 ; Bump error count, etc. ; ; Got SOH or STX - get block number, block number complemented ; @@ -3457,9 +3475,18 @@ RSDMA: LXI D,TBUF ; Reset DMA address WRERR: CALL RSDMA ; Reset DMA to normal MVI C,CAN ; Cancel CALL SEND ; Sender +; [WBW] BEGIN: RCVSABT does not return, so file write error +; message was never being displayed. Swapped things around +; to fix this. +; CALL RCVSABT ; Kill receive file +; CALL ERXIT ; Exit with msg: +; DB '++ Error writing file ++$' +; [WBW] ----- + CALL ILPRT ; Dispaly error msg + DB CR,LF,'++ Error writing file ++',CR,LF,0 CALL RCVSABT ; Kill receive file - CALL ERXIT ; Exit with msg: - DB '++ Error writing file ++$' +; [WBW] END + ; ; Receive a character - timeout time is in 'B' in seconds. Entry via ; 'RECVDG' deletes garbage characters on the line. For example, having @@ -3470,11 +3497,17 @@ RECVDG: CALL GETCHR CALL GETCHR ; RECV: PUSH D ; Save 'DE' regs. -;WBW BEGIN: Use dynamic CPU speed +; +; [WBW] BEGIN: Check immediately for char pending to avoid delay + CALL RCVRDY ; Input from modem ready + JZ MCHAR ; Got the character +; [WBW] END +; +; [WBW] BEGIN: Use dynamic CPU speed ; MVI E,MHZ ; Get the clock speed LDA CPUMHZ ; Get the clock speed MOV E,A ; Put speed in E -;WBW END +; [WBW] END XRA A ; Clear the 'A' reg. ; MSLOOP: ADD B ; Number of seconds @@ -3483,12 +3516,12 @@ MSLOOP: ADD B ; Number of seconds MOV B,A ; Put total value back into 'B' ; MSEC: IF NOT BYEBDOS -;WBW BEGIN: Use scalar passed in by patch +; [WBW] BEGIN: Use scalar passed in by patch ;LXI D,6600 ; 1 second DCR count XCHG LHLD RCVSCL ; Use scalar value from patch XCHG -;WBW END +; [WBW] END ENDIF ; IF BYEBDOS @@ -3567,7 +3600,7 @@ CARCK2: LDA OPTSAV ; Get option ; Delay - 100 millisecond delay. ; DELAY: PUSH B ; Save 'BC' -; WBW BEGIN: Use dynamic CPU speed +; [WBW] BEGIN: Use dynamic CPU speed ; Loop below is 105TS on Z80 and 96TS on Z180 ; Approx 1024 iter per 100ms per MHz ; Loop time below extended to accommodate CPU speeds up to 64MHz @@ -3578,7 +3611,7 @@ DELAY: PUSH B ; Save 'BC' RLC ; * 2, A now has MHz * 4 MOV B,A ; Use as high byte MVI C,0 ; Zero low byte, BC now has MHz * 1024 -; WBW END +; [WBW] END DELAY2: DCX B ; Update count MOV A,B ; Get MSP byte ORA C ; Count = zero? @@ -3967,7 +4000,7 @@ INPUT: PUSH H ; Save current values PUSH D PUSH B ; -; WBW BEGIN: Use dynamic CPU speed +; [WBW] BEGIN: Use dynamic CPU speed ;INPUT1: LXI D,1200 ; Outer loop count (about 2 minutes) ;; ;INPUT2: LXI B,MHZ*100 ; Roughly 100 ms. @@ -3976,7 +4009,7 @@ INPUT1: LXI D,468 ; Outer loop count (about 2 minutes) INPUT2: LDA CPUMHZ ; CPU MHz to A MOV B,A ; Put in B MVI C,0 ; Zero C, BC is now CPU MHz * 256, ~256ms -; WBW END +; [WBW] END ; INPUT3: PUSH D ; Save the outer delay count PUSH B ; Save the inner delay count @@ -5655,8 +5688,9 @@ MSGFLG: DB 0 ; Message upload flag SAVEHL: DW 0 ; Saves TBUF command line address TOTERR: DW 0 ; Total errors for transmission attempt VRECNO: DW 0 ; Virtual record # in 128 byte records -CPUMHZ: DB MHZ ; WBW: CPU speed in MHz -RCVSCL: DW SCL ; WBW: Recv loop scalar +CPUMHZ: DB MHZ ; [WBW] CPU speed in MHz +RCVSCL: DW SCL ; [WBW] Recv loop scalar +PORT: DB 0FFH ; [WBW] Target serial port, FFH=not specified ; EOFLG: DB 0 ; 'EOF' flag (1=yes) EOFCTR: DB 0 ; EOF send counter @@ -5685,7 +5719,8 @@ OLINE: DS 80 ; Temporary buffer to store line ORG ($+127)/128*128 ; DBUF EQU $ ; 16-record disk buffer -STACK EQU DBUF-2 ; Save original stack address +;STACK EQU DBUF-2 ; Save original stack address +STACK EQU 0B000H ; [WBW] Above 8000h for HBIOS Fastpath LOGBUF EQU DBUF+128 ; For use with LOGCAL ; ;----------------------------------------------------------------------- diff --git a/Source/Apps/XM/xmhb.180 b/Source/Apps/XM/xmhb.180 index 8f926794..8d4cb406 100644 --- a/Source/Apps/XM/xmhb.180 +++ b/Source/Apps/XM/xmhb.180 @@ -4,22 +4,15 @@ ; ; Wayne Warthen - wwarthen@gmail.com ; -; 2018-06-06 WBW Added support for RC2014 w/ Z180 -; 2019-08-17 WBW Refactored and merged Phil's ECB-FIFO support -; 2019-08-28 WBW Refactored ASCI support +; 2020-05-23 WBW Rewrite for HBIOS FastPath(tm) ; ;======================================================================= ; ASEG ; -NO EQU 0 -YES EQU NOT NO +BASE EQU 100H ; Start of CP/M normal program area ; -ERRDET EQU NO ; detect parity/framing/overrun errs -; -BASE EQU 100H ; start of cp/m normal program area -; -BDOS EQU 00005H ; BDOS function dispatch vector +BDOS EQU 0005H ; BDOS function dispatch vector ; ;======================================================================= ; @@ -59,8 +52,10 @@ CONOUT EQU 0 ; not used ; entries as appropriate. ; MINIT: + LD (UNIT),A ; Save port specified + ; Announce - LD DE,RBC ; RetroBrew Computers + LD DE,TAG ; Tagline LD C,9 ; BDOS string display function CALL BDOS ; Do it ; @@ -68,42 +63,17 @@ MINIT: CALL IDBIO ; 1=HBIOS, 2=UBIOS LD (BIOID),A ; Save it DEC A ; Test for HBIOS - JR Z,HINIT ; Do HBIOS setup + JR Z,MINIT_HB ; Do HBIOS setup DEC A ; Test for UBIOS - JR Z,UINIT ; Do UBIOS setup + JR Z,MINIT_UB ; Do UBIOS setup ; ; Neither UNA nor RomWBW LD DE,ERR_BIO ; BIOS error message - LD C,9 ; BDOS string display function - CALL BDOS ; Do it - JP 0 ; Bail out! + JP FAIL ; Print msg and bail out ; -MINIT_RET: - PUSH HL ; Save HL (JP table adr) - - ; Display port notification string - LD C,9 ; BDOS string display function - CALL BDOS ; Do it -; - ; Newline - LD C,9 ; BDOS string display function - LD DE,CRLF ; Newline - CALL BDOS ; Do it -; - ; Copy real vectors into active jump table - POP HL ; Recover HL - LD DE,JPTBL ; Real jump table is destination - LD BC,7 * 3 ; Copy 7 3-byte entries - LDIR ; Do the copy -; - ; Return with CPU speed in A - LD A,(CPUSPD) ; A := CPU speed in MHz - LD HL,(RCVSCL) ; HL := receive scalar - RET ; and return -; -HINIT: +MINIT_HB: ; Display RomWBW notification string - LD DE,HBTAG ; BIOS notification string + LD DE,HB_TAG ; BIOS notification string LD C,9 ; BDOS string display function CALL BDOS ; Do it ; @@ -114,22 +84,42 @@ HINIT: LD A,L ; Move it to A LD (CPUSPD),A ; Save it ; - ; Get HBIOS character 0 device type - LD B,006H ; HBIOS DEVICE function 0x06 - LD C,000H ; HBIOS char 0 device + ; Get HBIOS bank id + LD BC,0F8F2H ; HBIOS SYSGET, Bank Info + RST 08 ; do it + JP NZ,APIERR ; handle API error + LD A,D ; BIOS bank id to A + LD (BIOSBID),A ; save it +; + LD A,(UNIT) ; get current unit specified + CP 0FFH ; check for undefined + JR NZ,MINIT_HB1 ; if not undefined, go ahead +; + ; Lookup current console to use as default for transfer + LD B,0FAH ; HBIOS PEEK + LD A,(BIOSBID) ; get BIOS bank id + LD D,A ; ... and put in D + LD HL,100H + 12H ; HCB console unit address + RST 08 ; E := value + LD A,E ; put in A + LD (UNIT),A ; replace UNIT with console UNIT +; +MINIT_HB1: + ; Get HBIOS device type + LD B,06H ; HBIOS DEVICE function 0x06 + LD A,(UNIT) ; Get xfer unit + LD C,A ; Put in C RST 08 ; Do it, D=device type LD A,D ; Put result in A - CP 000H ; UART? - JP Z,U_INIT ; If so, do UART init - CP 010H ; ASCI? - JP Z,A_INIT ; If so, do ASCI init - CP 080H ; USB-FIFO? - JP Z,UF_INIT ; If so, do USB-FIFO init - JP H_INIT ; Otherwise, use HBIOS I/O -; -UINIT: + CP 00H ; UART? + JP Z,UA_INIT ; If so, do UART H/W init + CP 80H ; USB-FIFO? + JP Z,UF_INIT ; If so, do USB-FIFO H/W init + JP HB_INIT ; Otherwise, use BIOS I/O +; +MINIT_UB: ; Display UNA notification string - LD DE,UBTAG ; BIOS notification string + LD DE,UB_TAG ; BIOS notification string LD C,9 ; BDOS string display function CALL BDOS ; Do it ; @@ -137,27 +127,78 @@ UINIT: LD C,0F8H ; UNA BIOS Get PHI function RST 08 ; Returns speed in Hz in DE:HL LD B,4 ; Divide MHz in DE:HL by 100000H -UINIT1: +MINIT_UB1: SRL D ; ... to get approx CPU speed in RR E ; ...MHz. Throw away HL, and - DJNZ UINIT1 ; ...right shift DE by 4. + DJNZ MINIT_UB1 ; ...right shift DE by 4. INC E ; Fix up for value truncation LD A,E ; Put in A LD (CPUSPD),A ; Save it ; - ; Check CPU, Z80=UART, Z180=ASCI - LD DE,00202H ; D := 2, E := 2 - MLT DE ; DE := D * E == 4 - BIT 2,E ; Bit 2 wil be set if mlt happend - JP Z,U_INIT ; UART initialization - JP A_INIT ; otherwise, ASCI + JP UB_INIT ; UNA BIOS init ; -HWERR: - ; Failed to identify target comm hardware - LD DE,ERR_HW ; Hardware error message +MINIT_RET: + PUSH HL ; Save HL (JP table adr) + + ; Display handler label LD C,9 ; BDOS string display function CALL BDOS ; Do it - JP 0 ; Bail out! +; + ; Display port (unit number) + LD DE,COM_LBL ; Prefix + LD C,9 ; BDOS string display function + CALL BDOS ; Do it + LD A,(UNIT) ; Get unit number + ADD A,'0' ; Make displayable + LD E,A ; Put in E for display + LD C,2 ; BDOS console write char + CALL BDOS ; Do it +; + ; Newline + LD C,9 ; BDOS string display function + LD DE,CRLF ; Newline + CALL BDOS ; Do it +; + ; Copy real vectors into active jump table + POP HL ; Recover HL + LD DE,JPTBL ; Real jump table is destination + LD BC,7 * 3 ; Copy 7 3-byte entries + LDIR ; Do the copy +; + ; Return with CPU speed in A + LD A,(CPUSPD) ; A := CPU speed in MHz + LD HL,(RCVSCL) ; HL := receive scalar + RET ; and return +; +;----------------------------------------------------------------------- +; +; Uninitialize modem +; +UNINIT: + LD A,(BIOID) + CP 1 ; Is HBIOS? + JR Z,HUNINIT ; Handle HBIOS + CP 2 ; Is UBIOS? + JR Z,UUNINIT ; Handle UBIOS + RET ; Just return +; +HUNINIT: + ; HBIOS: Reset character device 0 + LD B,04H ; HBIOS CIOINIT function 0x04 + LD A,(UNIT) ; HBIOS serial unit number + LD C,A ; Put in C for func call + LD DE,-1 ; Reset w/ current settings + RST 08 ; Do it + RET ; not initialized, so no 'UN-INITIALIZE' +; +UUNINIT: + ; UBIOS: Reset character device 0 + LD C,10H ; UNA INIT function 0x10 + LD A,(UNIT) ; UBIOS serial unit number + LD B,A ; Put in B for func call + LD DE,-1 ; Reset w/ current settings + RST 08 ; Do it + RET ; not initialized, so no 'UN-INITIALIZE' ; ; Identify active BIOS. RomWBW HBIOS=1, UNA UBIOS=2, else 0 ; @@ -196,33 +237,21 @@ IDBIO2: XOR A ; Setup return value of 0 RET ; and done ; -;----------------------------------------------------------------------- +HWERR: + ; Failed to identify target comm hardware + LD DE,ERR_HW ; Hardware error message + JP FAIL ; Print message and bail out ; -; Uninitialize modem +APIERR: + ; API returned unepected failure + LD DE,ERR_API ; API error message + JP FAIL ; Pprint message and bail out ; -UNINIT: - LD A,(BIOID) - CP 1 ; Is HBIOS? - JR Z,H_UNINIT ; Handle HBIOS - CP 2 ; Is UBIOS? - JR Z,U_UNINIT ; Handle UBIOS - RET ; Just return -; -H_UNINIT: - ; HBIOS: Reset character device 0 - LD B,04H ; HBIOS CIOINIT function 0x04 - LD C,0 ; Unit = 0 - LD DE,-1 ; Reset w/ current settings - RST 08 ; Do it - RET ; not initialized, so no 'UN-INITIALIZE' -; -U_UNINIT: - ; UBIOS: Reset character device 0 - LD C,10H ; UNA INIT function 0x10 - LD B,0 ; Unit = 0 - LD DE,-1 ; Reset w/ current settings - RST 08 ; Do it - RET ; not initialized, so no 'UN-INITIALIZE' +FAIL: + ; DE has error string address + LD C,9 ; BDOS string display function + CALL BDOS ; Do it + JP 0 ; Bail out! ; ;----------------------------------------------------------------------- ; @@ -244,95 +273,150 @@ EXTRA3: BIOID DB 0 ; BIOS ID, 1=HBIOS, 2=UBIOS CPUSPD DB 10 ; CPU speed in MHz RCVSCL DW 6600 ; RECV loop timeout scalar +UNIT DB 0 ; BIOS serial device unit number +BIOSBID DB 00H ; BIOS bank id ; -RBC DB "RBC, 28-Aug-2019$" +TAG DB "RomWBW, 30-May-2020$" ; -U_LBL DB ", UART$" -A_LBL DB ", ASCI$" -S_LBL DB ", SIO$" -H_LBL DB ", COM$" +HB_LBL DB ", HBIOS FastPath$" +UB_LBL DB ", UNA UBIOS$" +UA_LBL DB ", UART$" UF_LBL DB ", USB-FIFO$" +COM_LBL DB " on COM$" ; -UBTAG DB " [UNA]$" -HBTAG DB " [WBW]$" +UB_TAG DB " [UNA]$" +HB_TAG DB " [WBW]$" ; CRLF DB 13, 10, "$" ; ERR_BIO DB 13, 10, 13, 10, "++ Unknown BIOS ++", 13, 10, "$" ERR_HW DB 13, 10, 13, 10, "++ Unknown Hardware ++", 13, 10, "$" +ERR_API DB 13, 10, 13, 10, "++ BIOS API Error ++", 13, 10, "$" ; ;======================================================================= ;======================================================================= ; -; 8250-like UART @ Port 68H +; RomWBW HBIOS Interface ; ;======================================================================= ;======================================================================= ; -; UART port constants -; -U_BASE EQU 68H ; UART base port -U_DATP EQU U_BASE + 0 ; data in port -U_DATO EQU U_BASE + 0 ; data out port -U_CTLP EQU U_BASE + 5 ; control/status port -U_SNDB EQU 20H ; bit to test for send ready -U_SNDR EQU 20H ; value when ready to send -U_RCVB EQU 01H ; bit to test for receive ready -U_RCVR EQU 01H ; value when ready to receive -U_PARE EQU 04H ; bit for parity error -U_OVRE EQU 02H ; bit for overrun error -U_FRME EQU 08H ; bit for framing error -U_ERRS EQU U_FRME | U_OVRE | U_PARE -; -; Following jump table is dynamically patched into real jump +; Following jump table is dynamically patched over initial jump ; table at program startup. See MINIT above. Note that only a ; subset of the jump table is overlaid (SENDR to SPEED). ; -U_JPTBL: - JP U_SENDR ; send character (via pop psw) - JP U_CAROK ; test for carrier - JP U_MDIN ; receive data byte - JP U_GETCHR ; get character from modem - JP U_RCVRDY ; check receive ready - JP U_SNDRDY ; check send ready - JP U_SPEED ; get speed value for file transfer time +HB_JPTBL: + JP HB_SENDR ; send character (via pop psw) + JP HB_CAROK ; test for carrier + JP HB_MDIN ; receive data byte + JP HB_GETCHR ; get character from modem + JP HB_RCVRDY ; check receive ready + JP HB_SNDRDY ; check send ready + JP HB_SPEED ; get speed value for file transfer time ; ;----------------------------------------------------------------------- ; -; UART initialization +; HBIOS initialization ; -U_INIT: - LD HL,13000 ; Receive loop timeout scalar - LD (RCVSCL),HL ; ... for UART RCVRDY timing +HB_INIT: + LD HL,2150 ; Smaller receive loop timeout scalar + LD (RCVSCL),HL ; ... to compensate for BIOS overhead ; - LD HL,U_JPTBL - LD DE,U_LBL + ; Patch SENDR w/ FastPath addresses + LD BC,0F801H ; Get CIO func/data adr + LD D,01H ; Func=CIO OUT + LD A,(UNIT) ; get desired char unit + LD E,A ; and put in E + RST 08 + JP NZ,APIERR ; handle API error + LD (HB_UDAT),DE ; Plug in data adr + LD (HB_SCFN),HL ; Plug in func adr +; + ; Patch GETCHR/MDIN w/ FastPath addresses + LD BC,0F801H ; Get CIO func/data adr + LD D,00H ; Func=CIO IN + LD A,(UNIT) ; get desired char unit + LD E,A ; and put in E + RST 08 + JP NZ,APIERR ; handle API error + LD (HB_GCFN),HL ; Plug in func adr +; + ; Patch RCVRDY w/ FastPath addresses + LD BC,0F801H ; Get CIO func/data adr + LD D,02H ; Func=CIO IST + LD A,(UNIT) ; get desired char unit + LD E,A ; and put in E + RST 08 + JP NZ,APIERR ; handle API error + LD (HB_RRFN),HL ; Plug in func adr +; + ; Patch SNDRDY w/ FastPath addresses + LD BC,0F801H ; Get CIO func/data adr + LD D,03H ; Func=CIO OST + LD A,(UNIT) ; get desired char unit + LD E,A ; and put in E + RST 08 + JP NZ,APIERR ; handle API error + LD (HB_SRFN),HL ; Plug in func adr +; + LD HL,HB_JPTBL + LD DE,HB_LBL JP MINIT_RET ; ;----------------------------------------------------------------------- ; ; Send character on top of stack ; -U_SENDR: +HB_SENDR: POP AF ; get character to send from stack - OUT (U_DATO),A ; send to port + PUSH BC + PUSH DE + PUSH HL + LD E,A ; character to E + LD IY,(HB_UDAT) + LD A,(BIOSBID) ; call into HBIOS bank + LD IX,0000H +HB_SCFN EQU $-2 + CALL 0FFF9H ; HBIOS bank call + POP HL + POP DE + POP BC RET ; ;----------------------------------------------------------------------- ; ; Test and report carrier status, Z set if carrier present ; -U_CAROK: +HB_CAROK: XOR A ; not used, always indicate present RET ; ;----------------------------------------------------------------------- ; -; Get a character (assume character ready has already been tested) +; Get a character +; +; GETCHR must not block +; +HB_GETCHR: + CALL HB_RCVRDY + RET NZ + ; Fall thru if char ready ; -U_MDIN: -U_GETCHR: - IN A,(U_DATP) ; read character from port +; MDIN can assume a character is ready +; +HB_MDIN: + PUSH BC + PUSH DE + PUSH HL + LD IY,(HB_UDAT) + LD A,(BIOSBID) ; call into HBIOS bank + LD IX,0000H +HB_GCFN EQU $-2 + CALL 0FFF9H ; HBIOS bank call + LD A,E ; byte received to A + POP HL + POP DE + POP BC RET ; ;----------------------------------------------------------------------- @@ -341,309 +425,144 @@ U_GETCHR: ; Error code returned in A register ; *** Error code does not seem to be used *** ; -U_RCVRDY: - IN A,(U_CTLP) ; get modem status -; - IF ERRDET -; - ; With error detection (slower) - PUSH BC ; save scratch register - PUSH AF ; save full status on stack - AND U_ERRS ; isolate line err bits - LD B,A ; save err status in B - POP AF ; get full status back - AND U_RCVB ; isolate ready bit - CP U_RCVR ; test it (set flags) - LD A,B ; get the error code back - POP BC ; restore scratch register -; - ELSE -; - ; No error detection (faster) - AND U_RCVB ; isolate ready bit - CP U_RCVR ; test it (set flags) +HB_RCVRDY: + PUSH BC + PUSH DE + PUSH HL + LD IY,(HB_UDAT) + LD A,(BIOSBID) ; call into HBIOS bank + LD IX,0000H +HB_RRFN EQU $-2 + CALL 0FFF9H ; HBIOS bank call + SUB 1 ; CF set IFF zero + RL A ; CF to bit 0 of A + AND 01H ; set Z flag as needed LD A,0 ; report no line errors -; - ENDIF -; + POP HL + POP DE + POP BC RET ; ;----------------------------------------------------------------------- ; ; Test for ready to send a character, Z = ready ; -U_SNDRDY: - IN A,(U_CTLP) ; get status - AND U_SNDB ; isolate transmit ready bit - CP U_SNDR ; test for ready value +HB_SNDRDY: + PUSH BC + PUSH DE + PUSH HL + LD IY,(HB_UDAT) + LD A,(BIOSBID) ; call into HBIOS bank + LD IX,0000H +HB_SRFN EQU $-2 + CALL 0FFF9H ; HBIOS bank call + SUB 1 ; CF set IFF zero + RL A ; CF to bit 0 of A + AND 01H ; set Z flag as needed + POP HL + POP DE + POP BC RET ; ;----------------------------------------------------------------------- ; ; Report baud rate (index into SPTBL returned in register A) ; -U_SPEED: +HB_SPEED: LD A,8 ; arbitrarily return 9600 baud RET ; -;======================================================================= -;======================================================================= -; -; Z180 Primary ASCI -; -; - Port is determined dynamically in A_INIT -; -;======================================================================= -;======================================================================= -; -; ASCI port constants -; -A_DATP EQU 08H ; Z180 TSR - ASCI receive data port -A_DATO EQU 06H ; Z180 TDR - ASCI transmit data port -A_CTLP EQU 04H ; Z180 STAT - ASCI status port -A_CTL2 EQU 00H ; Z180 CNTLA - ASCI control port -; -A_SNDB EQU 02H ; Z180 STAT:TDRE - xmit data reg empty bit -A_SNDR EQU 02H ; Z180 STAT:TDRE - xmit data reg empty value -A_RCVB EQU 80H ; Z180 STAT:RDRF - rcv data reg full bit -A_RCVR EQU 80H ; Z180 STAT:RDRF - rcv data reg full value -A_PARE EQU 20H ; Z180 STAT:PE - parity error bit -A_OVRE EQU 40H ; Z180 STAT:OVRN - overrun error bit -A_FRME EQU 10H ; Z180 STAT:FE - framing error bit -A_ERRS EQU A_FRME | A_OVRE | A_PARE -; -A_BASE DB 00H ; internal IO base address for Z180 -; -; Following jump table is dynamically patched over initial jump -; table at program startup. See MINIT above. Note that only a -; subset of the jump table is overlaid (SENDR to SPEED). -; -A_JPTBL: - JP A_SENDR ; send character (via pop psw) - JP A_CAROK ; test for carrier - JP A_MDIN ; receive data byte - JP A_GETCHR ; get character from modem - JP A_RCVRDY ; check receive ready - JP A_SNDRDY ; check send ready - JP A_SPEED ; get speed value for file transfer time -; -;----------------------------------------------------------------------- -; -; ASCI initialization -; -A_INIT: - LD HL,7500 ; Receive loop timeout scalar - LD (RCVSCL),HL ; ... for ASCI RCVRDY timing -; - ; Test for location of Z180 internal registers - ; and use appropriate I/O address. - LD B,0 ; set MSB for 16 bit I/O - LD C,040H|3FH ; internal registers @ 40H? - IN A,(C) ; read - CP 040H|01FH ; same value except for bit 5? - JR Z,A_INIT1 ; do ASCI init (port in C) - LD C,0C0H|3FH ; internal registers @ C0H? - IN A,(C) ; read - CP 0C0H|1FH ; same value except for bit 5? - JR Z,A_INIT1 ; do ASCI init (port in C) - JP HWERR ; unknown hardware error -; -A_INIT1: - LD A,C ; test port value to A - AND 0C0H ; only top two bits relevant - LD (A_BASE),A ; save it - ADD A,A_CTLP ; status port offset - LD C,A ; put in C for I/O - LD B,0 ; MSB for 16 bit I/O - XOR A ; clear interrupt enable flags - OUT (C),A ; do it -; - LD HL,A_JPTBL - LD DE,A_LBL - JP MINIT_RET -; -;----------------------------------------------------------------------- -; -; Send character on top of stack -; -A_SENDR: - EX (SP),HL ; save HL, HL := char to send - PUSH BC ; save scratch register - LD A,(A_BASE) ; IO base address - ADD A,A_DATO ; data out port offset - LD C,A ; put in C for I/O - LD B,0 ; MSB for 16 bit I/O - OUT (C),H ; send to port - POP BC ; restore scratch reg - POP HL ; restore HL - RET ; done -; -;----------------------------------------------------------------------- -; -; Test and report carrier status, Z set if carrier present -; -A_CAROK: - XOR A ; not used, always indicate present - RET -; -;----------------------------------------------------------------------- -; -; Get a character (assume character ready has already been tested) -; -A_MDIN: -A_GETCHR: - PUSH BC ; save scratch register - LD A,(A_BASE) ; IO base address - ADD A,A_DATP ; data in port offset - LD C,A ; put in C for I/O - LD B,0 ; MSB for 16 bit I/O - IN A,(C) ; read character from port - POP BC ; restore scratch reg - RET -; -;----------------------------------------------------------------------- -; -; Test for character ready to receive, Z = ready -; Error code returned in A register -; *** Error code does not seem to be used *** ; -A_RCVRDY: - PUSH BC ; save scratch register - LD A,(A_BASE) ; IO base address - ADD A,A_CTLP ; status port offset - LD C,A ; put in C for I/O - LD B,0 ; MSB for 16 bit I/O - IN A,(C) ; get modem status - PUSH AF ; save full status on stack - AND A_ERRS ; isolate line err bits - LD B,A ; save err status in B - - ; Z180 ASCI ports will stall if there are errors. - ; Error bits are NOT cleared by merely reading - ; the status register. Below, bit 3 of ASCI - ; control register is written with a zero to - ; clear error(s) if needed. - JR Z,A_RCVRDY2 ; if no errs, continue - PUSH BC ; save scratch reg - LD A,(A_BASE) ; IO base address - ADD A,A_CTL2 ; status port offset - LD C,A ; put in C for I/O - LD B,0 ; MSB for 16 bit I/O - IN A,(C) ; get current control reg value - AND 0F7H ; force err reset bit to zero - OUT (C),A ; write control register - POP BC ; restore scratch reg -; -A_RCVRDY2: - POP AF ; get full status back - AND A_RCVB ; isolate ready bit - CP A_RCVR ; test it (set flags) - LD A,B ; get the error code back - POP BC ; restore scratch register - RET ; -;----------------------------------------------------------------------- +HB_UDAT DW 0000H ; Unit data address ; -; Test for ready to send a character, Z = ready -; -A_SNDRDY: - PUSH BC ; save scratch register - LD A,(A_BASE) ; IO base address - ADD A,A_CTLP ; status port offset - LD C,A ; put in C for I/O - LD B,0 ; MSB for 16 bit I/O - IN A,(C) ; get modem status - AND A_SNDB ; isolate transmit ready bit - CP A_SNDR ; test for ready value - POP BC ; restore scratch register - RET -; -;----------------------------------------------------------------------- -; -; Report baud rate (index into SPTBL returned in register A) -; -A_SPEED: - LD A,8 ; arbitrarily return 9600 baud - RET ; ;======================================================================= ;======================================================================= ; -; Zilog SIO @ Port 80H +; UNA UBIOS Interface ; ;======================================================================= ;======================================================================= ; -; Currently assumes the port address and ordering conventions of the -; official RC2014 SIO module. Will not work with others such as EZZ80 -; or ZP. -; -; SIO port constants -; -S_BASE EQU 80H ; SIO base port -S_DATP EQU S_BASE + 1 ; data in port -S_DATO EQU S_BASE + 1 ; data out port -S_CTLP EQU S_BASE + 0 ; control/status port -S_SNDB EQU 04H ; bit to test for send ready -S_SNDR EQU 04H ; value when ready to send -S_RCVB EQU 01H ; bit to test for receive ready -S_RCVR EQU 01H ; value when ready to receive -; -; Following jump table is dynamically patched into real jump +; Following jump table is dynamically patched over initial jump ; table at program startup. See MINIT above. Note that only a ; subset of the jump table is overlaid (SENDR to SPEED). ; -S_JPTBL: - JP S_SENDR ; send character (via pop psw) - JP S_CAROK ; test for carrier - JP S_MDIN ; receive data byte - JP S_GETCHR ; get character from modem - JP S_RCVRDY ; check receive ready - JP S_SNDRDY ; check send ready - JP S_SPEED ; get speed value for file transfer time +UB_JPTBL: + JP UB_SENDR ; send character (via pop psw) + JP UB_CAROK ; test for carrier + JP UB_MDIN ; receive data byte + JP UB_GETCHR ; get character from modem + JP UB_RCVRDY ; check receive ready + JP UB_SNDRDY ; check send ready + JP UB_SPEED ; get speed value for file transfer time ; ;----------------------------------------------------------------------- ; -; SIO initialization +; UBIOS initialization ; -S_INIT: - LD HL,12000 ; Receive loop timeout scalar - LD (RCVSCL),HL ; ... for UART RCVRDY timing +UB_INIT: ; - ; Suppress interrupts - LD A,01H ; WR1 - OUT (S_CTLP),A ; Select WR1 - XOR A ; No interrupts - OUT (S_CTLP),A ; Do it +; TODO: +; - TEST!!! +; - ADJUST RCVSCL? ; - LD HL,S_JPTBL - LD DE,S_LBL + LD HL,3000 ; Smaller receive loop timeout scalar + LD (RCVSCL),HL ; ... to compensate for BIOS overhead +; + LD HL,UB_JPTBL + LD DE,UB_LBL JP MINIT_RET ; ;----------------------------------------------------------------------- ; ; Send character on top of stack ; -S_SENDR: +UB_SENDR: POP AF ; get character to send from stack - OUT (S_DATO),A ; send to port + PUSH BC + PUSH DE + PUSH HL + LD BC,0012H ; unit 0, func 12h (write char) + LD E,A ; character to E + RST 08 + POP HL + POP DE + POP BC RET ; ;----------------------------------------------------------------------- ; ; Test and report carrier status, Z set if carrier present ; -S_CAROK: +UB_CAROK: XOR A ; not used, always indicate present RET ; ;----------------------------------------------------------------------- ; -; Get a character (assume character ready has already been tested) +; Get a character +; +; GETCHR must not block +; +UB_GETCHR: + CALL UB_RCVRDY + RET NZ + ; Fall thru if char ready +; +; MDIN can assume a character is ready ; -S_MDIN: -S_GETCHR: - IN A,(S_DATP) ; read character from port +UB_MDIN: + PUSH BC + PUSH DE + PUSH HL + LD BC,0011H ; unit 0, func 12h (write char) + RST 08 + LD A,E ; byte received to A + POP HL + POP DE + POP BC RET ; ;----------------------------------------------------------------------- @@ -652,121 +571,134 @@ S_GETCHR: ; Error code returned in A register ; *** Error code does not seem to be used *** ; -S_RCVRDY: - ;XOR A - ;OUT (S_CTLP),A ; select WR0 - IN A,(S_CTLP) ; get status - AND S_RCVB ; isolate ready bit - CP S_RCVR ; test it (set flags) +UB_RCVRDY: + PUSH BC + PUSH DE + PUSH HL + LD BC,0013H ; unit 0, func 13h (input stat) + RST 08 + XOR A ; zero accum ; 4 + CP E ; CF means not zero ; 4 + CCF ; CF means zero ; 4 + RLA ; ZF means not zero ; 4 LD A,0 ; report no line errors + POP HL + POP DE + POP BC RET ; ;----------------------------------------------------------------------- ; ; Test for ready to send a character, Z = ready ; -S_SNDRDY: - ;XOR A - ;OUT (S_CTLP),A ; select WR0 - IN A,(S_CTLP) ; get status - AND S_SNDB ; isolate ready bit - CP S_SNDR ; test it (set flags) - LD A,0 ; report no line errors +UB_SNDRDY: + PUSH BC + PUSH DE + PUSH HL + LD BC,0014H ; unit 0, func 14h (output stat) + RST 08 + XOR A ; zero accum ; 4 + CP E ; CF means not zero ; 4 + CCF ; CF means zero ; 4 + RLA ; ZF means not zero ; 4 + POP HL + POP DE + POP BC RET ; ;----------------------------------------------------------------------- ; ; Report baud rate (index into SPTBL returned in register A) ; -S_SPEED: +UB_SPEED: LD A,8 ; arbitrarily return 9600 baud RET ; ;======================================================================= ;======================================================================= ; -; HBIOS Console (COM0:) +; 8250-like UART ; ;======================================================================= ;======================================================================= ; -; Following jump table is dynamically patched over initial jump +; UART constants +; +UA_SNDB EQU 20H ; bit to test for send ready +UA_SNDR EQU 20H ; value when ready to send +UA_RCVB EQU 01H ; bit to test for receive ready +UA_RCVR EQU 01H ; value when ready to receive +UA_PARE EQU 04H ; bit for parity error +UA_OVRE EQU 02H ; bit for overrun error +UA_FRME EQU 08H ; bit for framing error +UA_ERRS EQU UA_FRME | UA_OVRE | UA_PARE +; +; Following jump table is dynamically patched into real jump ; table at program startup. See MINIT above. Note that only a ; subset of the jump table is overlaid (SENDR to SPEED). ; -H_JPTBL: - JP H_SENDR ; send character (via pop psw) - JP H_CAROK ; test for carrier - JP H_MDIN ; receive data byte - JP H_GETCHR ; get character from modem - JP H_RCVRDY ; check receive ready - JP H_SNDRDY ; check send ready - JP H_SPEED ; get speed value for file transfer time +UA_JPTBL: + JP UA_SENDR ; send character (via pop psw) + JP UA_CAROK ; test for carrier + JP UA_MDIN ; receive data byte + JP UA_GETCHR ; get character from modem + JP UA_RCVRDY ; check receive ready + JP UA_SNDRDY ; check send ready + JP UA_SPEED ; get speed value for file transfer time ; ;----------------------------------------------------------------------- ; -; HBIOS initialization +; UART initialization ; -H_INIT: - LD HL,1250 ; Smaller receive loop timeout scalar - LD (RCVSCL),HL ; ... to compensate for BIOS overhead +UA_INIT: + LD DE,13000 ; receive loop timeout scalar + LD (RCVSCL),DE ; ... for UART RCVRDY timing +; + LD A,L ; get base I/O port address + LD (UA_SCP),A ; set port value in SENDR + LD (UA_GCP),A ; set port value in GETCHR + ADD A,5 ; UART control port is 5 higher + LD (UA_RRP),A ; set port value in RCVRDY + LD (UA_SRP),A ; set port value in SNDRDY ; - LD HL,H_JPTBL - LD DE,H_LBL + LD HL,UA_JPTBL + LD DE,UA_LBL JP MINIT_RET ; ;----------------------------------------------------------------------- ; ; Send character on top of stack ; -H_SENDR: +UA_SENDR: POP AF ; get character to send from stack - PUSH BC - PUSH DE - PUSH HL - LD B,01H ; HBIOS OUT function - LD C,0 ; console is unit 0 by fiat - LD E,A ; character to E - RST 08 ; HBIOS call - POP HL - POP DE - POP BC + OUT (0FFH),A ; send to port +UA_SCP EQU $-1 ; port value RET ; ;----------------------------------------------------------------------- ; ; Test and report carrier status, Z set if carrier present ; -H_CAROK: +UA_CAROK: XOR A ; not used, always indicate present RET ; ;----------------------------------------------------------------------- ; -; Get a character (assume character ready has already been tested) +; Get a character ; -; This routine must NOT block. +; GETCHR must not block ; -H_MDIN: -H_GETCHR: - PUSH BC - PUSH DE - PUSH HL - LD B,02H ; HBIOS IST function - LD C,0 ; console is unit 0 by fiat - RST 08 ; HBIOS call, A := bytes pending - JR NZ,H_MDIN1 ; If char(s) waiting, go get it - XOR A ; otherwise, return null - JR H_MDIN2 ; and done -H_MDIN1: - LD B,00H ; HBIOS IN function - LD C,0 ; console is unit 0 by fiat - RST 08 ; HBIOS call - LD A,E ; byte received to A -H_MDIN2: - POP HL - POP DE - POP BC +UA_GETCHR: + CALL UA_RCVRDY + RET NZ + ; Fall thru if char ready +; +; MDIN can assume a character is ready +; +UA_MDIN: + IN A,(0FFH) ; read character from port +UA_GCP EQU $-1 ; port value RET ; ;----------------------------------------------------------------------- @@ -775,50 +707,40 @@ H_MDIN2: ; Error code returned in A register ; *** Error code does not seem to be used *** ; -H_RCVRDY: - PUSH BC - PUSH DE - PUSH HL - LD B,02H ; HBIOS IST function - LD C,0 ; console is unit 0 by fiat - RST 08 ; HBIOS call, A := bytes pending - SUB 1 ; CF set IFF zero - RL A ; CF to bit 0 of A - AND 01H ; set Z flag as needed +UA_RCVRDY: + IN A,(0FFH) ; get modem status +UA_RRP EQU $-1 ; port value + AND UA_RCVB ; isolate ready bit + CP UA_RCVR ; test it (set flags) LD A,0 ; report no line errors - POP HL - POP DE - POP BC +; RET ; ;----------------------------------------------------------------------- ; ; Test for ready to send a character, Z = ready ; -H_SNDRDY: - PUSH BC - PUSH DE - PUSH HL - LD B,03H ; HBIOS OST function - LD C,0 ; console is unit 0 by fiat - RST 08 ; HBIOS call, A := xmit buf bytes avail - SUB 1 ; CF set IFF zero - RL A ; CF to bit 0 of A - AND 01H ; set Z flag as needed - POP HL - POP DE - POP BC +UA_SNDRDY: + IN A,(0FFH) ; get status +UA_SRP EQU $-1 ; port value + AND UA_SNDB ; isolate transmit ready bit + CP UA_SNDR ; test for ready value RET ; ;----------------------------------------------------------------------- ; ; Report baud rate (index into SPTBL returned in register A) ; -H_SPEED: +UA_SPEED: LD A,8 ; arbitrarily return 9600 baud RET ; ; +; +UA_BASE DB 00H ; UART base port I/O address +UA_CTLP DB 00H ; UART control port I/O address +; +; ;======================================================================= ;======================================================================= ; @@ -837,21 +759,30 @@ UF_SEND_IMM EQU (UF_BASE+2) ; subset of the jump table is overlaid (SENDR to SPEED). ; UF_JPTBL: - JP UF_SENDR ; send character (via pop psw) - JP UF_CAROK ; test for carrier - JP UF_MDIN ; receive data byte - JP UF_GETCHR ; get character from modem - JP UF_RCVRDY ; check receive ready - JP UF_SNDRDY ; check send ready - JP UF_SPEED ; get speed value for file transfer time + JP UF_SENDR ; send character (via pop psw) + JP UF_CAROK ; test for carrier + JP UF_MDIN ; receive data byte + JP UF_GETCHR ; get character from modem + JP UF_RCVRDY ; check receive ready + JP UF_SNDRDY ; check send ready + JP UF_SPEED ; get speed value for file transfer time ; ;----------------------------------------------------------------------- ; ; USB-FIFO initialization ; UF_INIT: - LD HL,12000 ; Receive loop timeout scalar - LD (RCVSCL),HL ; ... for UART RCVRDY timing + LD DE,12000 ; receive loop timeout scalar + LD (RCVSCL),DE ; ... for UART RCVRDY timing +; + LD A,L ; get base I/O port address (data port) + LD (UF_SCDP),A ; set data port in SENDR + LD (UF_GCDP),A ; set data port in GETCHR/MDIN + INC A ; bump to status port + LD (UF_RRSP),A ; set status port in RCVRDY + LD (UF_SRSP),A ; set status port in SNDRDY + INC A ; bump to send immediate port + LD (UF_SCIP),A ; set send immed port in SENDR ; LD HL,UF_JPTBL LD DE,UF_LBL @@ -863,9 +794,11 @@ UF_INIT: ; UF_SENDR: - POP AF ; get character to send from stack - OUT (UF_DATA),A ; WRITE TO FIFO - OUT (UF_SEND_IMM),A ; SEND IMMEDIATE + POP AF ; get character to send from stack + OUT (0FFH),A ; write to fifo +UF_SCDP EQU $-1 ; data port + OUT (0FFH),A ; send immediate +UF_SCIP EQU $-1 ; send immediate port RET ; ;----------------------------------------------------------------------- @@ -873,18 +806,25 @@ UF_SENDR: ; Test and report carrier status, Z set if carrier present ; UF_CAROK: - XOR A ; not used, always indicate present + XOR A ; not used, always indicate present RET ; ;----------------------------------------------------------------------- ; ; Get a character (assume character ready has already been tested) ; -; This routine must NOT block. +; GETCHR must not block ; -UF_MDIN: UF_GETCHR: - IN A,(UF_DATA) ; GET CHAR + CALL UF_RCVRDY ; check for char ready + RET NZ ; return if not + ; Fall thru if char ready +; +; MDIN can assume a character is ready +; +UF_MDIN: + IN A,(0FFH) ; get char +UF_GCDP EQU $-1 ; data port RET ; ;----------------------------------------------------------------------- @@ -894,10 +834,11 @@ UF_GETCHR: ; *** Error code does not seem to be used *** ; UF_RCVRDY: - IN A,(UF_STATUS) ; B7=0 IF CHAR AVAIL, =1 IF NO CHAR. - RLCA ; B0=0 IF CHAR AVAIL, =1 IF NO CHAR. - AND 00000001B ; A=0, ZF=1 IF NO CHAR, A=1, ZF=0 IF CHAR AVAIL, - LD A,0 + IN A,(0FFH) ; bit 7 = 0 if char avail, = 1 if no char. +UF_RRSP EQU $-1 ; status port + RLCA ; bit 0 = 0 if char avail, = 1 if no char. + AND 00000001B ; A = 0, ZF = 1 if no char, A = 1, ZF = 0 if char avail. + LD A,0 ; no errors RET ; ;----------------------------------------------------------------------- @@ -905,8 +846,9 @@ UF_RCVRDY: ; Test for ready to send a character, Z = ready ; UF_SNDRDY: - IN A,(UF_STATUS) ; Bit 0=0 IF SPACE AVAIL, =1 IF FULL - AND 00000001B ; A=0, ZF=1 IF SPACE AVAIL, A=1, ZF=0 IF FULL. + IN A,(0FFH) ; bit 0 = 0 if space avail, = 1 if full +UF_SRSP EQU $-1 ; status port + AND 00000001B ; A = 0, ZF = 1 if space avail, A = 1, ZF = 0 if full. RET ; ;----------------------------------------------------------------------- @@ -914,7 +856,7 @@ UF_SNDRDY: ; Report baud rate (index into SPTBL returned in register A) ; UF_SPEED: - LD A,8 ; arbitrarily return 9600 baud + LD A,8 ; arbitrarily return 9600 baud RET ; END diff --git a/Source/Apps/XM/xmhb_old.180 b/Source/Apps/XM/xmhb_old.180 new file mode 100644 index 00000000..8f926794 --- /dev/null +++ b/Source/Apps/XM/xmhb_old.180 @@ -0,0 +1,920 @@ +;======================================================================= +; +; XMHB.Z80 - XMODEM12 PATCH FILE FOR ROMWBW HBIOS +; +; Wayne Warthen - wwarthen@gmail.com +; +; 2018-06-06 WBW Added support for RC2014 w/ Z180 +; 2019-08-17 WBW Refactored and merged Phil's ECB-FIFO support +; 2019-08-28 WBW Refactored ASCI support +; +;======================================================================= +; + ASEG +; +NO EQU 0 +YES EQU NOT NO +; +ERRDET EQU NO ; detect parity/framing/overrun errs +; +BASE EQU 100H ; start of cp/m normal program area +; +BDOS EQU 00005H ; BDOS function dispatch vector +; +;======================================================================= +; +; Jump table: The jump table must be in exactly the same sequence as the +; one in XMODEM. Note the ORG of 103H - This jump table has no jump to +; 'BEGIN'. +; + ORG BASE + 3 ; start after 'JMP BEGIN' +; + JP CONOUT ; must be 00000h if not used, see below + JP MINIT ; initialization routine (if needed) + JP UNINIT ; undo whatever 'MINIT' did (or return) +JPTBL: + JP SENDR ; send character (via pop psw) + JP CAROK ; test for carrier + JP MDIN ; receive data byte + JP GETCHR ; get character from modem + JP RCVRDY ; check receive ready + JP SNDRDY ; check send ready + JP SPEED ; get speed value for file transfer time + JP EXTRA1 ; extra for custom routine + JP EXTRA2 ; extra for custom routine + JP EXTRA3 ; extra for custom routine +; +;----------------------------------------------------------------------- +; +; Output character to console +; +CONOUT EQU 0 ; not used +; +;----------------------------------------------------------------------- +; +; Initialize modem +; +; This procedure has been usurped to dynamically detect the type +; of system we are running on and install the *real* jump table +; entries as appropriate. +; +MINIT: + ; Announce + LD DE,RBC ; RetroBrew Computers + LD C,9 ; BDOS string display function + CALL BDOS ; Do it +; + ; Identify BIOS (RomWBW HBIOS or UNA UBIOS) + CALL IDBIO ; 1=HBIOS, 2=UBIOS + LD (BIOID),A ; Save it + DEC A ; Test for HBIOS + JR Z,HINIT ; Do HBIOS setup + DEC A ; Test for UBIOS + JR Z,UINIT ; Do UBIOS setup +; + ; Neither UNA nor RomWBW + LD DE,ERR_BIO ; BIOS error message + LD C,9 ; BDOS string display function + CALL BDOS ; Do it + JP 0 ; Bail out! +; +MINIT_RET: + PUSH HL ; Save HL (JP table adr) + + ; Display port notification string + LD C,9 ; BDOS string display function + CALL BDOS ; Do it +; + ; Newline + LD C,9 ; BDOS string display function + LD DE,CRLF ; Newline + CALL BDOS ; Do it +; + ; Copy real vectors into active jump table + POP HL ; Recover HL + LD DE,JPTBL ; Real jump table is destination + LD BC,7 * 3 ; Copy 7 3-byte entries + LDIR ; Do the copy +; + ; Return with CPU speed in A + LD A,(CPUSPD) ; A := CPU speed in MHz + LD HL,(RCVSCL) ; HL := receive scalar + RET ; and return +; +HINIT: + ; Display RomWBW notification string + LD DE,HBTAG ; BIOS notification string + LD C,9 ; BDOS string display function + CALL BDOS ; Do it +; + ; Get CPU speed from RomWBW HBIOS and save it + LD B,0F8H ; HBIOS SYSGET function 0xF8 + LD C,0F0H ; CPUINFO subfunction 0xF0 + RST 08 ; Do it, L := CPU speed in MHz + LD A,L ; Move it to A + LD (CPUSPD),A ; Save it +; + ; Get HBIOS character 0 device type + LD B,006H ; HBIOS DEVICE function 0x06 + LD C,000H ; HBIOS char 0 device + RST 08 ; Do it, D=device type + LD A,D ; Put result in A + CP 000H ; UART? + JP Z,U_INIT ; If so, do UART init + CP 010H ; ASCI? + JP Z,A_INIT ; If so, do ASCI init + CP 080H ; USB-FIFO? + JP Z,UF_INIT ; If so, do USB-FIFO init + JP H_INIT ; Otherwise, use HBIOS I/O +; +UINIT: + ; Display UNA notification string + LD DE,UBTAG ; BIOS notification string + LD C,9 ; BDOS string display function + CALL BDOS ; Do it +; + ; Get CPU speed from UNA and save it + LD C,0F8H ; UNA BIOS Get PHI function + RST 08 ; Returns speed in Hz in DE:HL + LD B,4 ; Divide MHz in DE:HL by 100000H +UINIT1: + SRL D ; ... to get approx CPU speed in + RR E ; ...MHz. Throw away HL, and + DJNZ UINIT1 ; ...right shift DE by 4. + INC E ; Fix up for value truncation + LD A,E ; Put in A + LD (CPUSPD),A ; Save it +; + ; Check CPU, Z80=UART, Z180=ASCI + LD DE,00202H ; D := 2, E := 2 + MLT DE ; DE := D * E == 4 + BIT 2,E ; Bit 2 wil be set if mlt happend + JP Z,U_INIT ; UART initialization + JP A_INIT ; otherwise, ASCI +; +HWERR: + ; Failed to identify target comm hardware + LD DE,ERR_HW ; Hardware error message + LD C,9 ; BDOS string display function + CALL BDOS ; Do it + JP 0 ; Bail out! +; +; Identify active BIOS. RomWBW HBIOS=1, UNA UBIOS=2, else 0 +; +IDBIO: +; + ; Check for UNA (UBIOS) + LD A,(0FFFDH) ; fixed location of UNA API vector + CP 0C3H ; jp instruction? + JR NZ,IDBIO1 ; if not, not UNA + LD HL,(0FFFEH) ; get jp address + LD A,(HL) ; get byte at target address + CP 0FDH ; first byte of UNA push ix instruction + JR NZ,IDBIO1 ; if not, not UNA + INC HL ; point to next byte + LD A,(HL) ; get next byte + CP 0E5H ; second byte of UNA push ix instruction + JR NZ,IDBIO1 ; if not, not UNA, check others + LD A,2 ; UNA BIOS id = 2 + RET ; and done +; +IDBIO1: + ; Check for RomWBW (HBIOS) + LD HL,(0FFFEH) ; HL := HBIOS ident location + LD A,'W' ; First byte of ident + CP (HL) ; Compare + JR NZ,IDBIO2 ; Not HBIOS + INC HL ; Next byte of ident + LD A,~'W' ; Second byte of ident + CP (HL) ; Compare + JR NZ,IDBIO2 ; Not HBIOS + LD A,1 ; HBIOS BIOS id = 1 + RET ; and done +; +IDBIO2: + ; No idea what this is + XOR A ; Setup return value of 0 + RET ; and done +; +;----------------------------------------------------------------------- +; +; Uninitialize modem +; +UNINIT: + LD A,(BIOID) + CP 1 ; Is HBIOS? + JR Z,H_UNINIT ; Handle HBIOS + CP 2 ; Is UBIOS? + JR Z,U_UNINIT ; Handle UBIOS + RET ; Just return +; +H_UNINIT: + ; HBIOS: Reset character device 0 + LD B,04H ; HBIOS CIOINIT function 0x04 + LD C,0 ; Unit = 0 + LD DE,-1 ; Reset w/ current settings + RST 08 ; Do it + RET ; not initialized, so no 'UN-INITIALIZE' +; +U_UNINIT: + ; UBIOS: Reset character device 0 + LD C,10H ; UNA INIT function 0x10 + LD B,0 ; Unit = 0 + LD DE,-1 ; Reset w/ current settings + RST 08 ; Do it + RET ; not initialized, so no 'UN-INITIALIZE' +; +;----------------------------------------------------------------------- +; +; The following are all dummy routines that are unused because MINIT +; dynamically installs the real jump table. +; +SENDR: +CAROK: +MDIN: +GETCHR: +RCVRDY: +SNDRDY: +SPEED: +EXTRA1: +EXTRA2: +EXTRA3: + RET +; +BIOID DB 0 ; BIOS ID, 1=HBIOS, 2=UBIOS +CPUSPD DB 10 ; CPU speed in MHz +RCVSCL DW 6600 ; RECV loop timeout scalar +; +RBC DB "RBC, 28-Aug-2019$" +; +U_LBL DB ", UART$" +A_LBL DB ", ASCI$" +S_LBL DB ", SIO$" +H_LBL DB ", COM$" +UF_LBL DB ", USB-FIFO$" +; +UBTAG DB " [UNA]$" +HBTAG DB " [WBW]$" +; +CRLF DB 13, 10, "$" +; +ERR_BIO DB 13, 10, 13, 10, "++ Unknown BIOS ++", 13, 10, "$" +ERR_HW DB 13, 10, 13, 10, "++ Unknown Hardware ++", 13, 10, "$" +; +;======================================================================= +;======================================================================= +; +; 8250-like UART @ Port 68H +; +;======================================================================= +;======================================================================= +; +; UART port constants +; +U_BASE EQU 68H ; UART base port +U_DATP EQU U_BASE + 0 ; data in port +U_DATO EQU U_BASE + 0 ; data out port +U_CTLP EQU U_BASE + 5 ; control/status port +U_SNDB EQU 20H ; bit to test for send ready +U_SNDR EQU 20H ; value when ready to send +U_RCVB EQU 01H ; bit to test for receive ready +U_RCVR EQU 01H ; value when ready to receive +U_PARE EQU 04H ; bit for parity error +U_OVRE EQU 02H ; bit for overrun error +U_FRME EQU 08H ; bit for framing error +U_ERRS EQU U_FRME | U_OVRE | U_PARE +; +; Following jump table is dynamically patched into real jump +; table at program startup. See MINIT above. Note that only a +; subset of the jump table is overlaid (SENDR to SPEED). +; +U_JPTBL: + JP U_SENDR ; send character (via pop psw) + JP U_CAROK ; test for carrier + JP U_MDIN ; receive data byte + JP U_GETCHR ; get character from modem + JP U_RCVRDY ; check receive ready + JP U_SNDRDY ; check send ready + JP U_SPEED ; get speed value for file transfer time +; +;----------------------------------------------------------------------- +; +; UART initialization +; +U_INIT: + LD HL,13000 ; Receive loop timeout scalar + LD (RCVSCL),HL ; ... for UART RCVRDY timing +; + LD HL,U_JPTBL + LD DE,U_LBL + JP MINIT_RET +; +;----------------------------------------------------------------------- +; +; Send character on top of stack +; +U_SENDR: + POP AF ; get character to send from stack + OUT (U_DATO),A ; send to port + RET +; +;----------------------------------------------------------------------- +; +; Test and report carrier status, Z set if carrier present +; +U_CAROK: + XOR A ; not used, always indicate present + RET +; +;----------------------------------------------------------------------- +; +; Get a character (assume character ready has already been tested) +; +U_MDIN: +U_GETCHR: + IN A,(U_DATP) ; read character from port + RET +; +;----------------------------------------------------------------------- +; +; Test for character ready to receive, Z = ready +; Error code returned in A register +; *** Error code does not seem to be used *** +; +U_RCVRDY: + IN A,(U_CTLP) ; get modem status +; + IF ERRDET +; + ; With error detection (slower) + PUSH BC ; save scratch register + PUSH AF ; save full status on stack + AND U_ERRS ; isolate line err bits + LD B,A ; save err status in B + POP AF ; get full status back + AND U_RCVB ; isolate ready bit + CP U_RCVR ; test it (set flags) + LD A,B ; get the error code back + POP BC ; restore scratch register +; + ELSE +; + ; No error detection (faster) + AND U_RCVB ; isolate ready bit + CP U_RCVR ; test it (set flags) + LD A,0 ; report no line errors +; + ENDIF +; + RET +; +;----------------------------------------------------------------------- +; +; Test for ready to send a character, Z = ready +; +U_SNDRDY: + IN A,(U_CTLP) ; get status + AND U_SNDB ; isolate transmit ready bit + CP U_SNDR ; test for ready value + RET +; +;----------------------------------------------------------------------- +; +; Report baud rate (index into SPTBL returned in register A) +; +U_SPEED: + LD A,8 ; arbitrarily return 9600 baud + RET +; +;======================================================================= +;======================================================================= +; +; Z180 Primary ASCI +; +; - Port is determined dynamically in A_INIT +; +;======================================================================= +;======================================================================= +; +; ASCI port constants +; +A_DATP EQU 08H ; Z180 TSR - ASCI receive data port +A_DATO EQU 06H ; Z180 TDR - ASCI transmit data port +A_CTLP EQU 04H ; Z180 STAT - ASCI status port +A_CTL2 EQU 00H ; Z180 CNTLA - ASCI control port +; +A_SNDB EQU 02H ; Z180 STAT:TDRE - xmit data reg empty bit +A_SNDR EQU 02H ; Z180 STAT:TDRE - xmit data reg empty value +A_RCVB EQU 80H ; Z180 STAT:RDRF - rcv data reg full bit +A_RCVR EQU 80H ; Z180 STAT:RDRF - rcv data reg full value +A_PARE EQU 20H ; Z180 STAT:PE - parity error bit +A_OVRE EQU 40H ; Z180 STAT:OVRN - overrun error bit +A_FRME EQU 10H ; Z180 STAT:FE - framing error bit +A_ERRS EQU A_FRME | A_OVRE | A_PARE +; +A_BASE DB 00H ; internal IO base address for Z180 +; +; Following jump table is dynamically patched over initial jump +; table at program startup. See MINIT above. Note that only a +; subset of the jump table is overlaid (SENDR to SPEED). +; +A_JPTBL: + JP A_SENDR ; send character (via pop psw) + JP A_CAROK ; test for carrier + JP A_MDIN ; receive data byte + JP A_GETCHR ; get character from modem + JP A_RCVRDY ; check receive ready + JP A_SNDRDY ; check send ready + JP A_SPEED ; get speed value for file transfer time +; +;----------------------------------------------------------------------- +; +; ASCI initialization +; +A_INIT: + LD HL,7500 ; Receive loop timeout scalar + LD (RCVSCL),HL ; ... for ASCI RCVRDY timing +; + ; Test for location of Z180 internal registers + ; and use appropriate I/O address. + LD B,0 ; set MSB for 16 bit I/O + LD C,040H|3FH ; internal registers @ 40H? + IN A,(C) ; read + CP 040H|01FH ; same value except for bit 5? + JR Z,A_INIT1 ; do ASCI init (port in C) + LD C,0C0H|3FH ; internal registers @ C0H? + IN A,(C) ; read + CP 0C0H|1FH ; same value except for bit 5? + JR Z,A_INIT1 ; do ASCI init (port in C) + JP HWERR ; unknown hardware error +; +A_INIT1: + LD A,C ; test port value to A + AND 0C0H ; only top two bits relevant + LD (A_BASE),A ; save it + ADD A,A_CTLP ; status port offset + LD C,A ; put in C for I/O + LD B,0 ; MSB for 16 bit I/O + XOR A ; clear interrupt enable flags + OUT (C),A ; do it +; + LD HL,A_JPTBL + LD DE,A_LBL + JP MINIT_RET +; +;----------------------------------------------------------------------- +; +; Send character on top of stack +; +A_SENDR: + EX (SP),HL ; save HL, HL := char to send + PUSH BC ; save scratch register + LD A,(A_BASE) ; IO base address + ADD A,A_DATO ; data out port offset + LD C,A ; put in C for I/O + LD B,0 ; MSB for 16 bit I/O + OUT (C),H ; send to port + POP BC ; restore scratch reg + POP HL ; restore HL + RET ; done +; +;----------------------------------------------------------------------- +; +; Test and report carrier status, Z set if carrier present +; +A_CAROK: + XOR A ; not used, always indicate present + RET +; +;----------------------------------------------------------------------- +; +; Get a character (assume character ready has already been tested) +; +A_MDIN: +A_GETCHR: + PUSH BC ; save scratch register + LD A,(A_BASE) ; IO base address + ADD A,A_DATP ; data in port offset + LD C,A ; put in C for I/O + LD B,0 ; MSB for 16 bit I/O + IN A,(C) ; read character from port + POP BC ; restore scratch reg + RET +; +;----------------------------------------------------------------------- +; +; Test for character ready to receive, Z = ready +; Error code returned in A register +; *** Error code does not seem to be used *** +; +A_RCVRDY: + PUSH BC ; save scratch register + LD A,(A_BASE) ; IO base address + ADD A,A_CTLP ; status port offset + LD C,A ; put in C for I/O + LD B,0 ; MSB for 16 bit I/O + IN A,(C) ; get modem status + PUSH AF ; save full status on stack + AND A_ERRS ; isolate line err bits + LD B,A ; save err status in B + + ; Z180 ASCI ports will stall if there are errors. + ; Error bits are NOT cleared by merely reading + ; the status register. Below, bit 3 of ASCI + ; control register is written with a zero to + ; clear error(s) if needed. + JR Z,A_RCVRDY2 ; if no errs, continue + PUSH BC ; save scratch reg + LD A,(A_BASE) ; IO base address + ADD A,A_CTL2 ; status port offset + LD C,A ; put in C for I/O + LD B,0 ; MSB for 16 bit I/O + IN A,(C) ; get current control reg value + AND 0F7H ; force err reset bit to zero + OUT (C),A ; write control register + POP BC ; restore scratch reg +; +A_RCVRDY2: + POP AF ; get full status back + AND A_RCVB ; isolate ready bit + CP A_RCVR ; test it (set flags) + LD A,B ; get the error code back + POP BC ; restore scratch register + RET +; +;----------------------------------------------------------------------- +; +; Test for ready to send a character, Z = ready +; +A_SNDRDY: + PUSH BC ; save scratch register + LD A,(A_BASE) ; IO base address + ADD A,A_CTLP ; status port offset + LD C,A ; put in C for I/O + LD B,0 ; MSB for 16 bit I/O + IN A,(C) ; get modem status + AND A_SNDB ; isolate transmit ready bit + CP A_SNDR ; test for ready value + POP BC ; restore scratch register + RET +; +;----------------------------------------------------------------------- +; +; Report baud rate (index into SPTBL returned in register A) +; +A_SPEED: + LD A,8 ; arbitrarily return 9600 baud + RET +; +;======================================================================= +;======================================================================= +; +; Zilog SIO @ Port 80H +; +;======================================================================= +;======================================================================= +; +; Currently assumes the port address and ordering conventions of the +; official RC2014 SIO module. Will not work with others such as EZZ80 +; or ZP. +; +; SIO port constants +; +S_BASE EQU 80H ; SIO base port +S_DATP EQU S_BASE + 1 ; data in port +S_DATO EQU S_BASE + 1 ; data out port +S_CTLP EQU S_BASE + 0 ; control/status port +S_SNDB EQU 04H ; bit to test for send ready +S_SNDR EQU 04H ; value when ready to send +S_RCVB EQU 01H ; bit to test for receive ready +S_RCVR EQU 01H ; value when ready to receive +; +; Following jump table is dynamically patched into real jump +; table at program startup. See MINIT above. Note that only a +; subset of the jump table is overlaid (SENDR to SPEED). +; +S_JPTBL: + JP S_SENDR ; send character (via pop psw) + JP S_CAROK ; test for carrier + JP S_MDIN ; receive data byte + JP S_GETCHR ; get character from modem + JP S_RCVRDY ; check receive ready + JP S_SNDRDY ; check send ready + JP S_SPEED ; get speed value for file transfer time +; +;----------------------------------------------------------------------- +; +; SIO initialization +; +S_INIT: + LD HL,12000 ; Receive loop timeout scalar + LD (RCVSCL),HL ; ... for UART RCVRDY timing +; + ; Suppress interrupts + LD A,01H ; WR1 + OUT (S_CTLP),A ; Select WR1 + XOR A ; No interrupts + OUT (S_CTLP),A ; Do it +; + LD HL,S_JPTBL + LD DE,S_LBL + JP MINIT_RET +; +;----------------------------------------------------------------------- +; +; Send character on top of stack +; +S_SENDR: + POP AF ; get character to send from stack + OUT (S_DATO),A ; send to port + RET +; +;----------------------------------------------------------------------- +; +; Test and report carrier status, Z set if carrier present +; +S_CAROK: + XOR A ; not used, always indicate present + RET +; +;----------------------------------------------------------------------- +; +; Get a character (assume character ready has already been tested) +; +S_MDIN: +S_GETCHR: + IN A,(S_DATP) ; read character from port + RET +; +;----------------------------------------------------------------------- +; +; Test for character ready to receive, Z = ready +; Error code returned in A register +; *** Error code does not seem to be used *** +; +S_RCVRDY: + ;XOR A + ;OUT (S_CTLP),A ; select WR0 + IN A,(S_CTLP) ; get status + AND S_RCVB ; isolate ready bit + CP S_RCVR ; test it (set flags) + LD A,0 ; report no line errors + RET +; +;----------------------------------------------------------------------- +; +; Test for ready to send a character, Z = ready +; +S_SNDRDY: + ;XOR A + ;OUT (S_CTLP),A ; select WR0 + IN A,(S_CTLP) ; get status + AND S_SNDB ; isolate ready bit + CP S_SNDR ; test it (set flags) + LD A,0 ; report no line errors + RET +; +;----------------------------------------------------------------------- +; +; Report baud rate (index into SPTBL returned in register A) +; +S_SPEED: + LD A,8 ; arbitrarily return 9600 baud + RET +; +;======================================================================= +;======================================================================= +; +; HBIOS Console (COM0:) +; +;======================================================================= +;======================================================================= +; +; Following jump table is dynamically patched over initial jump +; table at program startup. See MINIT above. Note that only a +; subset of the jump table is overlaid (SENDR to SPEED). +; +H_JPTBL: + JP H_SENDR ; send character (via pop psw) + JP H_CAROK ; test for carrier + JP H_MDIN ; receive data byte + JP H_GETCHR ; get character from modem + JP H_RCVRDY ; check receive ready + JP H_SNDRDY ; check send ready + JP H_SPEED ; get speed value for file transfer time +; +;----------------------------------------------------------------------- +; +; HBIOS initialization +; +H_INIT: + LD HL,1250 ; Smaller receive loop timeout scalar + LD (RCVSCL),HL ; ... to compensate for BIOS overhead +; + LD HL,H_JPTBL + LD DE,H_LBL + JP MINIT_RET +; +;----------------------------------------------------------------------- +; +; Send character on top of stack +; +H_SENDR: + POP AF ; get character to send from stack + PUSH BC + PUSH DE + PUSH HL + LD B,01H ; HBIOS OUT function + LD C,0 ; console is unit 0 by fiat + LD E,A ; character to E + RST 08 ; HBIOS call + POP HL + POP DE + POP BC + RET +; +;----------------------------------------------------------------------- +; +; Test and report carrier status, Z set if carrier present +; +H_CAROK: + XOR A ; not used, always indicate present + RET +; +;----------------------------------------------------------------------- +; +; Get a character (assume character ready has already been tested) +; +; This routine must NOT block. +; +H_MDIN: +H_GETCHR: + PUSH BC + PUSH DE + PUSH HL + LD B,02H ; HBIOS IST function + LD C,0 ; console is unit 0 by fiat + RST 08 ; HBIOS call, A := bytes pending + JR NZ,H_MDIN1 ; If char(s) waiting, go get it + XOR A ; otherwise, return null + JR H_MDIN2 ; and done +H_MDIN1: + LD B,00H ; HBIOS IN function + LD C,0 ; console is unit 0 by fiat + RST 08 ; HBIOS call + LD A,E ; byte received to A +H_MDIN2: + POP HL + POP DE + POP BC + RET +; +;----------------------------------------------------------------------- +; +; Test for character ready to receive, Z = ready +; Error code returned in A register +; *** Error code does not seem to be used *** +; +H_RCVRDY: + PUSH BC + PUSH DE + PUSH HL + LD B,02H ; HBIOS IST function + LD C,0 ; console is unit 0 by fiat + RST 08 ; HBIOS call, A := bytes pending + SUB 1 ; CF set IFF zero + RL A ; CF to bit 0 of A + AND 01H ; set Z flag as needed + LD A,0 ; report no line errors + POP HL + POP DE + POP BC + RET +; +;----------------------------------------------------------------------- +; +; Test for ready to send a character, Z = ready +; +H_SNDRDY: + PUSH BC + PUSH DE + PUSH HL + LD B,03H ; HBIOS OST function + LD C,0 ; console is unit 0 by fiat + RST 08 ; HBIOS call, A := xmit buf bytes avail + SUB 1 ; CF set IFF zero + RL A ; CF to bit 0 of A + AND 01H ; set Z flag as needed + POP HL + POP DE + POP BC + RET +; +;----------------------------------------------------------------------- +; +; Report baud rate (index into SPTBL returned in register A) +; +H_SPEED: + LD A,8 ; arbitrarily return 9600 baud + RET +; +; +;======================================================================= +;======================================================================= +; +; WILL SOWERBUTTS ECB USB-FIFO +; +;======================================================================= +;======================================================================= +; +UF_BASE EQU 0CH +UF_DATA EQU (UF_BASE+0) +UF_STATUS EQU (UF_BASE+1) +UF_SEND_IMM EQU (UF_BASE+2) +; +; Following jump table is dynamically patched over initial jump +; table at program startup. See MINIT above. Note that only a +; subset of the jump table is overlaid (SENDR to SPEED). +; +UF_JPTBL: + JP UF_SENDR ; send character (via pop psw) + JP UF_CAROK ; test for carrier + JP UF_MDIN ; receive data byte + JP UF_GETCHR ; get character from modem + JP UF_RCVRDY ; check receive ready + JP UF_SNDRDY ; check send ready + JP UF_SPEED ; get speed value for file transfer time +; +;----------------------------------------------------------------------- +; +; USB-FIFO initialization +; +UF_INIT: + LD HL,12000 ; Receive loop timeout scalar + LD (RCVSCL),HL ; ... for UART RCVRDY timing +; + LD HL,UF_JPTBL + LD DE,UF_LBL + JP MINIT_RET +; +;----------------------------------------------------------------------- +; +; Send character on top of stack +; +UF_SENDR: + + POP AF ; get character to send from stack + OUT (UF_DATA),A ; WRITE TO FIFO + OUT (UF_SEND_IMM),A ; SEND IMMEDIATE + RET +; +;----------------------------------------------------------------------- +; +; Test and report carrier status, Z set if carrier present +; +UF_CAROK: + XOR A ; not used, always indicate present + RET +; +;----------------------------------------------------------------------- +; +; Get a character (assume character ready has already been tested) +; +; This routine must NOT block. +; +UF_MDIN: +UF_GETCHR: + IN A,(UF_DATA) ; GET CHAR + RET +; +;----------------------------------------------------------------------- +; +; Test for character ready to receive, Z = ready +; Error code returned in A register +; *** Error code does not seem to be used *** +; +UF_RCVRDY: + IN A,(UF_STATUS) ; B7=0 IF CHAR AVAIL, =1 IF NO CHAR. + RLCA ; B0=0 IF CHAR AVAIL, =1 IF NO CHAR. + AND 00000001B ; A=0, ZF=1 IF NO CHAR, A=1, ZF=0 IF CHAR AVAIL, + LD A,0 + RET +; +;----------------------------------------------------------------------- +; +; Test for ready to send a character, Z = ready +; +UF_SNDRDY: + IN A,(UF_STATUS) ; Bit 0=0 IF SPACE AVAIL, =1 IF FULL + AND 00000001B ; A=0, ZF=1 IF SPACE AVAIL, A=1, ZF=0 IF FULL. + RET +; +;----------------------------------------------------------------------- +; +; Report baud rate (index into SPTBL returned in register A) +; +UF_SPEED: + LD A,8 ; arbitrarily return 9600 baud + RET +; + END diff --git a/Source/BPBIOS/diskdefs b/Source/BPBIOS/diskdefs index 937bfcf2..db9ef4b2 100644 --- a/Source/BPBIOS/diskdefs +++ b/Source/BPBIOS/diskdefs @@ -297,121 +297,169 @@ diskdef wbw_rom1024 os 2.2 end -# UNA 512KB ROM (128KB reserved, 384KB ROM Disk) +# RomWBW 720K floppy media +diskdef wbw_fd720 + seclen 512 + tracks 160 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom512 +# RomWBW 1.44M floppy media +diskdef wbw_fd144 seclen 512 - tracks 12 - sectrk 64 + tracks 160 + sectrk 18 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# UNA 512KB ROM (128KB reserved, 896KB ROM Disk) +# RomWBW 360K floppy media +diskdef wbw_fd360 + seclen 512 + tracks 80 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom1024 +# RomWBW 1.20M floppy media +diskdef wbw_fd120 seclen 512 - tracks 28 - sectrk 64 + tracks 160 + sectrk 15 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# RomWBW 8MB Hard Disk, LU 0-3 -diskdef wbw_hd0 +# RomWBW 8320KB Hard Disk Slice (512 directory entry format) +# Legacy format, 512 dir entries, 16,630 sectors / slice +diskdef wbw_hd512 seclen 512 - tracks 65 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 1 + boottrk 16 os 2.2 end -diskdef wbw_hd1 +# First 4 slices of wbw_hd512 +diskdef wbw_hd512_0 seclen 512 - tracks 130 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 66 + boottrk 16 os 2.2 end -diskdef wbw_hd2 +diskdef wbw_hd512_1 seclen 512 - tracks 195 - sectrk 256 + tracks 2080 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 131 + boottrk 1056 os 2.2 end -diskdef wbw_hd3 +diskdef wbw_hd512_2 seclen 512 - tracks 260 - sectrk 256 + tracks 3120 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 196 + boottrk 2096 os 2.2 end -# RomWBW 720K floppy media -diskdef wbw_fd720 +diskdef wbw_hd512_3 seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 4160 + sectrk 16 + blocksize 4096 + maxdir 512 skew 0 - boottrk 4 + boottrk 3136 os 2.2 end -# RomWBW 1.44M floppy media -diskdef wbw_fd144 + +# RomWBW 8MB Hard Disk (1024 directory entry format) +# New format, 1024 dir entries, 16,384 sectors / slice +# Pure filesystem image, no MBR prefix +diskdef wbw_hd1024 seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 + tracks 1024 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 boottrk 2 os 2.2 end -# RomWBW 360K floppy media -diskdef wbw_fd360 +# First 4 slices of wbw_hd1024 +# Assumes 128KB prefix (256 sectors) +diskdef wbw_hd1024_0 seclen 512 - tracks 80 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 1040 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 18 os 2.2 end -# RomWBW 1.20M floppy media -diskdef wbw_fd120 +diskdef wbw_hd1024_1 seclen 512 - tracks 160 - sectrk 15 - blocksize 2048 - maxdir 256 + tracks 2064 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 1042 + os 2.2 +end + +diskdef wbw_hd1024_2 + seclen 512 + tracks 3112 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 2066 + os 2.2 +end + +diskdef wbw_hd1024_3 + seclen 512 + tracks 4136 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 3114 os 2.2 end diff --git a/Source/BuildZRC.cmd b/Source/BuildZRC.cmd new file mode 100644 index 00000000..4c037580 --- /dev/null +++ b/Source/BuildZRC.cmd @@ -0,0 +1,4 @@ +@echo off +setlocal + +setlocal & cd ZRC && call Build || exit /b 1 & endlocal diff --git a/Source/CBIOS/cbios.asm b/Source/CBIOS/cbios.asm index 5f627426..4af347ef 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -10,8 +10,8 @@ ; 1) STACK LOCATION DURING BOOT OR WBOOT??? ; 2) REVIEW USE OF DI/EI IN INIT ; -FALSE .EQU 0 -TRUE .EQU ~FALSE +FALSE .EQU 0 +TRUE .EQU ~FALSE ; BDOS .EQU 5 ; BDOS FUNC INVOCATION VECTOR ; @@ -56,8 +56,8 @@ DEV_NUL .EQU $FF ; NUL: ; ; MEMORY LAYOUT ; -IOBYTE .EQU 3 ; LOC IN PAGE 0 OF I/O DEFINITION BYTE -CDISK .EQU 4 ; LOC IN PAGE 0 OF CURRENT DISK NUMBER 0=A,...,15=P +IOBYTE .EQU 3 ; LOC IN PAGE 0 OF I/O DEFINITION BYTE +CDISK .EQU 4 ; LOC IN PAGE 0 OF CURRENT DISK NUMBER 0=A,...,15=P ; CCP_LOC .EQU CPM_LOC CCP_SIZ .EQU $800 @@ -78,7 +78,7 @@ MEMTOP .EQU $10000 #INCLUDE "../UBIOS/ubios.inc" #ENDIF ; - .ORG CBIOS_LOC ; DEFINED IN STD.ASM + .ORG CBIOS_LOC ; DEFINED IN STD.ASM ; STACK .EQU CBIOS_END ; USE SLACK SPACE FOR STACK AS NEEDED ; @@ -112,7 +112,7 @@ WBOOTE JP WBOOT ; #1 - WARM START ; ; RomWBW CBIOS places the following stamp data into page zero ; at address $40. The address range $40-$4F is reserved by CP/M -; as a scratch area for CBIOS. This data below is copied there at +; as a scratch area for CBIOS. This data below is copied there at ; every warm start. It allows applications to identify RomWBW CBIOS. ; Additionally, it contains a pointer to additional CBIOS extension ; data (CBX) specific to RomWBW CBIOS. @@ -130,7 +130,7 @@ STPIMG: .DB 'W',~'W' ; MARKER STPSIZ .EQU $ - STPIMG ; ; The following section contains key information and addresses for the -; RomWBW CBIOS. A pointer to the start of this section is stored with +; RomWBW CBIOS. A pointer to the start of this section is stored with ; with the CBX data in page zero at $44 (see above). ; CBX: @@ -152,15 +152,15 @@ CBXSIZ .EQU $ - CBX ; IOBYTE (0003H) ; ============== ; -; Device LST: PUN: RDR: CON: -; Bit positions 7 6 5 4 3 2 1 0 +; Device LST: PUN: RDR: CON: +; Bit positions 7 6 5 4 3 2 1 0 ; -; Dec Binary +; Dec Binary ; -; 0 00 TTY: TTY: TTY: TTY: -; 1 01 CRT: PTP: PTR: CRT: -; 2 10 LPT: UP1: UR1: BAT: -; 3 11 UL1: UP2: UR2: UC1: +; 0 00 TTY: TTY: TTY: TTY: +; 1 01 CRT: PTP: PTR: CRT: +; 2 10 LPT: UP1: UR1: BAT: +; 3 11 UL1: UP2: UR2: UC1: ; ; TTY: Teletype device (slow speed console) ; CRT: Cathode ray tube device (high speed console) @@ -235,7 +235,7 @@ DEVMAP: ;================================================================================================== ; ; Disk mapping is done using a drive map table (DRVMAP) which is built -; dynamically at cold boot. See the DRV_INIT routine. This table is +; dynamically at cold boot. See the DRV_INIT routine. This table is ; made up of entries as documented below. The table is prefixed with one ; byte indicating the number of entries. The position of the entry indicates ; the drive letter, so the first entry is A:, the second entry is B:, etc. @@ -245,27 +245,27 @@ DEVMAP: ; DPH: DPH ADDRESS OF DRIVE (WORD) ; ; DRVMAP --+ -; | DRIVE A | DRIVE B | | DRIVE N | -; +-----V------+-------+-----+--------------------+ +--------------------+ -; | N | UNIT | SLICE | DPH | UNIT | SLICE | DPH | ... | UNIT | SLICE | DPH | -; +----8+-----8+------8+-+-16+-----8+------8+-+-16+ +-----8+------8+-+-16+ -; | | | -; +--------------------+ +-> [DPH] +-> [DPH] -; | -; V-----+-------+-------+-------+--------+-----+-----+-----+ -; DPH: | XLT | 0000H | 0000H | 0000H | DIRBUF | DPB | CSV | ALV | -; +---16+-----16+-----16+-----16+------16+-+-16+-+-16+-+-16+ -; (ONE DPH PER DRIVE) | | | -; | | +----------+ -; | | | -; +----------------------+ V-------------+ V-------------+ -; | | CSV BUF | | ALV BUF | -; | +-------------+ +-------------+ -; | (CSZ BYTES) (ASZ BYTES) -; | -; +-----+-----+-----V-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ -; DPB: | CSZ | ASZ | BLS | SPT | BSH | BLM | EXM | DSM | DRM | AL0 | AL1 | CKS | OFF | -; +---16+---16+----8+---16+----8+----8+----8+---16+---16+----8+----8+---16+---16+ +; | DRIVE A | DRIVE B | | DRIVE N | +; +-----V------+-------+-----+--------------------+ +--------------------+ +; | N | UNIT | SLICE | DPH | UNIT | SLICE | DPH | ... | UNIT | SLICE | DPH | +; +----8+-----8+------8+-+-16+-----8+------8+-+-16+ +-----8+------8+-+-16+ +; | | | +; +--------------------+ +-> [DPH] +-> [DPH] +; | +; V-----+-------+-------+-------+--------+-----+-----+-----+--------+ +; DPH: | XLT | 0000H | 0000H | 0000H | DIRBUF | DPB | CSV | ALV | LBAOFF | +; +---16+-----16+-----16+-----16+------16+-+-16+-+-16+-+-16+------32+ +; (ONE DPH PER DRIVE) | | | +; | | +----------+ +; | | | +; +----------------------+ V-------------+ V-------------+ +; | | CSV BUF | | ALV BUF | +; | +-------------+ +-------------+ +; | (CSZ BYTES) (ASZ BYTES) +; | +; +-----+-----+-----V-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ +; DPB: | CSZ | ASZ | BLS | SPT | BSH | BLM | EXM | DSM | DRM | AL0 | AL1 | CKS | OFF | +; +---16+---16+----8+---16+----8+----8+----8+---16+---16+----8+----8+---16+---16+ ; |<--- PREFIX ---->|<------------------- STANDARD CP/M DPB ------------------->| ; ;================================================================================================== @@ -289,6 +289,7 @@ DPBMAP: .DW DPB_FD360 ; MID_FD360 .DW DPB_FD120 ; MID_FD120 .DW DPB_FD111 ; MID_FD111 + .DW DPB_HDNEW ; MID_HDNEW (1024 DIR ENTRIES) ; DPBCNT .EQU ($ - DPBMAP) / 2 ; @@ -299,7 +300,8 @@ DPBCNT .EQU ($ - DPBMAP) / 2 ;__________________________________________________________________________________________________ BOOT: ; STANDARD BOOT INVOCATION - LD SP,STACK ; STACK FOR INITIALIZATION + ;LD SP,STACK ; STACK FOR INITIALIZATION + LD SP,CCP_LOC ; PUT STACK JUST BELOW CCP ; ; COPY INITIALIZATION CODE TO RUNNING LOCATION $8000 LD HL,BUFPOOL @@ -327,17 +329,20 @@ BOOT: ; ;__________________________________________________________________________________________________ REBOOT: - ; REBOOT FROM ROM, REPLACES BOOT AFTER INIT + ; RESTART, REPLACES BOOT AFTER INIT #IFDEF PLTUNA + ; FOR UNA, COLD BOOT DI ; NO INTERRUPTS LD BC,$01FB ; UNA FUNC = SET BANK LD DE,0 ; ROM BOOT BANK CALL $FFFD ; DO IT (RST 08 NOT SAFE HERE) #ENDIF +; #IFDEF PLTWBW - DI ; NO INTERRUPTS - LD A,0 ; ROM BOOT BANK - CALL HB_BNKSEL ; SELECT IT INTO LOW MEMORY + ; WARM START + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_WARM ; WARM START + CALL $FFF0 ; CALL HBIOS #ENDIF ; ; JUMP TO RESTART ADDRESS @@ -353,7 +358,7 @@ WBOOT: LD DE,(BNKBIOS) ; UBIOS_PAGE (SEE PAGES.INC) RST 08 ; DO IT PUSH DE ; SAVE PREVIOUS BANK - + LD HL,(CCPBUF) ; ADDRESS OF CCP BUF IN BIOS MEM LD DE,CCP_LOC ; ADDRESS IN HI MEM OF CCP LD BC,CCP_SIZ ; SIZE OF CCP @@ -383,11 +388,11 @@ WBOOT: LD BC,6 XOR A CALL FILL -; +; CALL RESCPM ; RESET CPM JR GOCPM ; THEN OFF TO CP/M WE GO... ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ RESCPM: ; LD A,$C3 ; LOAD A WITH 'JP' INSTRUCTION (USED BELOW) @@ -397,23 +402,13 @@ RESCPM: LD HL,WBOOTE ; GET WARM BOOT ENTRY ADDRESS LD ($0001),HL ; AND PUT IT AT $0001 -; ; INT / RST 38 -> INVOKE MONITOR -; LD ($0038),A -; LD HL,GOMON -; LD ($0039),HL - -; ; INT / RST 38 -> PANIC -; LD ($0038),A -; LD HL,PANIC ; PANIC ROUTINE ADDRESS -; LD ($0039),HL ; POKE IT - ; CALL 5 -> INVOKE BDOS LD ($0005),A ; JP OPCODE AT $0005 LD HL,BDOS_LOC + 6 ; GET BDOS ENTRY ADDRESS LD ($0006),HL ; PUT IT AT $0006 ; ; INSTALL ROMWBW CBIOS PAGE ZERO STAMP AT $40 - LD HL,STPIMG ; FORM STAMP DATA IMAGE + LD HL,STPIMG ; FROM STAMP DATA IMAGE LD DE,STPLOC ; TO IT'S LOCATION IN PAGE ZERO LD BC,STPSIZ ; SIZE OF BLOCK TO COPY LDIR ; DO IT @@ -427,7 +422,7 @@ RESCPM: ; RET ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ GOCPM: ; ; ENSURE VALID DISK AND JUMP TO CCP @@ -444,34 +439,12 @@ GOCCP: LD C,A ; SETUP C WITH CURRENT USER/DISK, ASSUME IT IS OK JP CCP_LOC ; JUMP TO COMMAND PROCESSOR ; -;__________________________________________________________________________________________________ -GOMON: - CALL PANIC -; -; DI -; IM 1 -; -; LD SP,STACK -; -; ; RELOAD MONITOR INTO RAM (IN CASE IT HAS BEEN OVERWRITTEN) -; CALL ROMPGZ -; LD HL,MON_IMG -; LD DE,MON_LOC -; LD BC,MON_SIZ -; LDIR -; CALL RAMPGZ - -; ; JUMP TO MONITOR WARM ENTRY -; JP MON_UART -; ; ;================================================================================================== ; CHARACTER BIOS FUNCTIONS ;================================================================================================== ; ;__________________________________________________________________________________________________ -; -;__________________________________________________________________________________________________ CONST: ; CONSOLE STATUS, RETURN $FF IF CHARACTER READY, $00 IF NOT ; @@ -479,7 +452,7 @@ CONST: LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE JR CONIO ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ CONIN: ; CONSOLE CHARACTER INTO REGISTER A ; @@ -487,7 +460,7 @@ CONIN: LD HL,CIOIN ; HL = ADDRESS OF COMPLETION ROUTINE JR CONIO -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ CONOUT: ; CONSOLE CHARACTER OUTPUT FROM REGISTER C ; @@ -496,7 +469,7 @@ CONOUT: LD E,C ; E = CHARACTER TO SEND ; JR CONIO ; COMMENTED OUT, FALL THROUGH OK ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ CONIO: ; LD A,(IOBYTE) ; GET IOBYTE @@ -504,8 +477,8 @@ CONIO: ;OR $00 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C JR CIO_DISP ; -;__________________________________________________________________________________________________ -LIST: +;__________________________________________________________________________________________________ +LIST: ; LIST CHARACTER FROM REGISTER C ; LD B,BF_CIOOUT ; B = FUNCTION @@ -513,7 +486,7 @@ LIST: LD E,C ; E = CHARACTER TO SEND JR LISTIO ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ LISTST: ; RETURN LIST STATUS (0 IF NOT READY, 1 IF READY) ; @@ -521,7 +494,7 @@ LISTST: LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE ;JR LISTIO ; COMMENTED OUT, FALL THROUGH OK ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ LISTIO: ; LD A,(IOBYTE) ; GET IOBYTE @@ -531,7 +504,7 @@ LISTIO: OR $0C ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C JR CIO_DISP ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ PUNCH: ; PUNCH CHARACTER FROM REGISTER C ; @@ -540,7 +513,7 @@ PUNCH: LD E,C ; E = CHARACTER TO SEND ;JR PUNCHIO ; COMMENTED OUT, FALL THROUGH OK ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ PUNCHIO: ; LD A,(IOBYTE) ; GET IOBYTE @@ -552,7 +525,7 @@ PUNCHIO: OR $08 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C JR CIO_DISP ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ READER: ; READ CHARACTER INTO REGISTER A FROM READER DEVICE ; @@ -560,7 +533,7 @@ READER: LD HL,CIOIN ; HL = ADDRESS OF COMPLETION ROUTINE JR READERIO ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ READERST: ; RETURN READER STATUS (0 IF NOT READY, 1 IF READY) ; @@ -568,7 +541,7 @@ READERST: LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE ; JR READERIO ; COMMENTED OUT, FALL THROUGH OK ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ READERIO: ; LD A,(IOBYTE) ; GET IOBYTE @@ -578,20 +551,20 @@ READERIO: OR $04 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C JR CIO_DISP ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ CIOIN: ; COMPLETION ROUTINE FOR CHARACTER INPUT FUNCTIONS ; LD A,E ; MOVE CHARACTER RETURNED TO A RET ; FALL THRU ;; -;;__________________________________________________________________________________________________ +;;__________________________________________________________________________________________________ ;CIOOUT: ;; COMPLETION ROUTINE FOR CHARACTER OUTPUT FUNCTIONS ;; ; RET ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ CIOST: ; COMPLETION ROUTINE FOR CHARACTER STATUS FUNCTIONS (IST/OST) ; @@ -621,7 +594,7 @@ CIO_DISP: LD HL,DEVMAP ; HL = ADDRESS OF DEVICE MAP CALL ADDHLA ; ADD OFFSET - + LD A,(HL) ; LOOKUP DEVICE CODE #IFDEF PLTUNA LD C,B ; MOVE FUNCTION TO C @@ -695,13 +668,13 @@ SELDSK: ; JP DSK_SELECT ; -;__________________________________________________________________________________________________ +;__________________________________________________________________________________________________ HOME: ; SELECT TRACK 0 (BC = 0) AND FALL THRU TO SETTRK #IF DSKTRACE CALL PRTHOME #ENDIF -; +; LD A,(HSTWRT) ; CHECK FOR PENDING WRITE OR A ; SET FLAGS JR NZ,HOMED ; BUFFER IS DIRTY @@ -764,7 +737,7 @@ BLKRES: XOR A LD (HSTACT),A ; BUFFER NO LONGER VALID LD (UNACNT),A ; CLEAR UNALLOC COUNT - + RET ;__________________________________________________________________________________________________ ; @@ -812,7 +785,7 @@ BLKRW: XOR A ; ZERO TO A LD (WRTYPE),A ; SET WRITE TYPE = 0 (WRT_ALC) TO ENSURE READ OCCURS LD (UNACNT),A ; SET UNACNT TO ABORT SEQ WRITE PROCESSING - + JR BLKRW4 ; GO TO I/O BLKRW1: @@ -821,7 +794,7 @@ BLKRW1: LD A,(WRTYPE) ; GET WRITE TYPE CP WRT_UNA ; IS IT WRITE TO UNALLOC? JR NZ,BLKRW2 ; NOPE, BYPASS - + ; INITIALIZE START OF SEQUENTIAL WRITING TO UNALLOCATED BLOCK ; AND THEN TREAT SUBSEQUENT PROCESSING AS A NORMAL WRITE CALL UNA_INI ; INITIALIZE SEQUENTIAL WRITE TRACKING @@ -835,11 +808,11 @@ BLKRW2: CALL UNA_CHK ; CHECK FOR CONTINUATION OF SEQ WRITES TO UNALLOCATED BLOCK JR NZ,BLKRW3 ; NOPE, ABORT - + ; WE MATCHED EVERYTHING, TREAT AS WRITE TO UNALLOCATED BLOCK LD A,WRT_UNA ; WRITE TO UNALLOCATED LD (WRTYPE),A ; SAVE WRITE TYPE - + CALL UNA_INC ; INCREMENT SEQUENTIAL WRITE TRACKING JR BLKRW4 ; PROCEED TO I/O PROCESSING @@ -870,16 +843,16 @@ BLKRW4: ; IMPLEMENT THE TRANSLATED VALUES CALL BLK_SAV ; SAVE XLAT VALUES: XLT... -> HST... - + ; IF WRITE TO UNALLOC BLOCK, BYPASS READ, LEAVES BUFFER UNDEFINED LD A,(WRTYPE) CP 2 JR Z,BLKRW6 - + ; DO THE ACTUAL READ CALL DSK_READ ; READ PHYSICAL SECTOR INTO BUFFER JR Z,BLKRW6 ; GOOD READ, CONTINUE - + ; IF READ FAILED, RESET (DE)BLOCKING ALGORITHM AND RETURN ERROR PUSH AF ; SAVE ERROR STATUS CALL BLKRES ; INVALIDATE (DE)BLOCKING BUFFER @@ -896,7 +869,7 @@ BLKRW6: CALL BLK_DEBLOCK ; EXTRACT DATA FROM BLOCK XOR A ; NO ERROR RET ; ALL DONE - + BLKRW7: ; THIS IS A WRITE OPERATION, INSERT DATA INTO BLOCK CALL BLK_BLOCK ; INSERT DATA INTO BLOCK @@ -904,7 +877,7 @@ BLKRW7: ; MARK THE BUFFER AS WRITTEN LD A,TRUE ; BUFFER DIRTY = TRUE LD (HSTWRT),A ; SAVE IT - + ; CHECK WRITE TYPE, IF WRT_DIR, FORCE THE PHYSICAL WRITE LD A,(WRTYPE) ; GET WRITE TYPE CP WRT_DIR ; 1 = DIRECTORY WRITE @@ -974,24 +947,24 @@ UNA_INC: ; DECREMENT THE BLOCK RECORD COUNT LD HL,UNACNT DEC (HL) - + ; INCREMENT THE SECTOR LD DE,(UNASEC) INC DE LD (UNASEC),DE - + ; CHECK FOR END OF TRACK LD HL,(UNASPT) XOR A SBC HL,DE RET NZ - + ; HANDLE END OF TRACK LD (UNASEC),HL ; SECTOR BACK TO 0 (NOTE: HL=0 AT THIS POINT) LD HL,(UNATRK) ; GET CURRENT TRACK INC HL ; BUMP IT LD (UNATRK),HL ; SAVE IT - + RET #ELSE ; @@ -1022,15 +995,15 @@ BLKRW1: CALL BLK_DEBLOCK ; EXTRACT DATA FROM BLOCK XOR A ; NO ERROR RET ; ALL DONE - + BLKRW2: CALL BLK_BLOCK ; INSERT DATA INTO BLOCK CALL DSK_WRITE ; WRITE PHYSICAL SECTOR FROM BUFFER RET NZ ; BAIL OUT ON ERROR - + LD A,TRUE ; BUFFER IS NOW VALID LD (HSTACT),A ; SAVE IT - + XOR A ; ALL IS WELL, SET RETURN CODE 0 RET ; RETURN #ENDIF @@ -1172,6 +1145,11 @@ DSK_GETINF: RLCA ; ... TO USE AS OFFSET INTO DRVMAP CALL ADDHLA ; ADD OFFSET LD D,(HL) ; D := UNIT + + LD A,D ; PUT UNIT IN ACCUM + INC A ; $FF -> $00 + JR Z,DSK_GETINF1 ; HANDLE UNASSIGNED DRIVE LETTER + INC HL ; BUMP TO SLICE LD E,(HL) ; E := SLICE INC HL ; POINT TO DPH LSB @@ -1179,9 +1157,11 @@ DSK_GETINF: INC HL ; POINT TO DPH MSB LD H,(HL) ; H := DPH MSB LD L,A ; L := DPH LSB - LD A,H ; TEST FOR INVALID DPH - OR L ; ... BY CHECKING FOR ZERO VALUE - JR Z,DSK_GETINF1 ; HANDLE ZERO DPH, DRIVE IS INVALID + + ;LD A,H ; TEST FOR INVALID DPH + ;OR L ; ... BY CHECKING FOR ZERO VALUE + ;JR Z,DSK_GETINF1 ; HANDLE ZERO DPH, DRIVE IS INVALID + XOR A ; SET SUCCESS RET ; @@ -1199,6 +1179,7 @@ DSK_GETINF1: ; ERROR RETURN DSK_SELECT: LD B,E ; SAVE E IN B FOR NOW CALL DSK_GETINF ; GET D=UNIT, E=SLICE, HL=DPH ADDRESS + ;CALL NZ,PANIC ; *DEBUG* RET NZ ; RETURN IF INVALID DRIVE (A=1, NZ SET, HL=0) PUSH BC ; WE NEED B LATER, SAVE ON STACK ; @@ -1209,23 +1190,50 @@ DSK_SELECT: LD (SEKUNIT),A ; SAVE UNIT LD (SEKDPH),HL ; SAVE DPH ADDRESS ; - ; UPDATE OFFSET FOR ACTIVE SLICE - ; A TRACK IS ASSUMED TO BE 16 SECTORS - ; THE OFFSET REPRESENTS THE NUMBER OF BLOCKS * 256 - ; TO USE AS THE OFFSET - LD H,65 ; H = TRACKS PER SLICE, E = SLICE NO - CALL MULT8 ; HL := H * E (TOTAL TRACK OFFSET) - LD (SEKOFF),HL ; SAVE NEW TRACK OFFSET + LD A,E ; A := SLICE + LD (SLICE),A ; SAVE IT + ; UPDATE LBAOFF FROM DPH + LD HL,(SEKDPH) + LD A,16 + CALL ADDHLA + LD DE,SEKLBA + LD BC,4 + LDIR ; ; RESTORE DE TO BC (FOR ACCESS TO DRIVE LOGIN BIT) POP BC ; GET ORIGINAL E INTO B -; -#IFDEF PLTWBW ; ; CHECK IF THIS IS LOGIN, IF NOT, BYPASS MEDIA DETECTION ; FIX: WHAT IF PREVIOUS MEDIA DETECTION FAILED??? BIT 0,B ; TEST DRIVE LOGIN BIT JR NZ,DSK_SELECT2 ; BYPASS MEDIA DETECTION +; +#IFDEF PLTUNA +; + LD A,(SEKUNIT) ; GET DISK UNIT + LD B,A ; UNIT NUM TO B + LD C,$48 ; UNA FUNC: GET DISK TYPE + CALL $FFFD ; CALL UNA + LD A,D ; MOVE DISK TYPE TO A + CP $40 ; RAM/ROM DRIVE? + JR Z,DSK_SELECT1 ; HANDLE RAM/ROM DRIVE + LD A,MID_HD ; OTHERWISE WE HAVE A HARD DISK + JR DSK_SELECT1A ; DONE +; +DSK_SELECT1: + ; UNA RAM/ROM DRIVE + LD C,$45 ; UNA FUNC: GET DISK INFO + LD DE,(DSKBUF) ; 512 BYTE BUFFER + CALL $FFFD ; CALL UNA + BIT 7,B ; TEST RAM DRIVE BIT + LD A,MID_MDROM ; ASSUME ROM + JR Z,DSK_SELECT1A ; IS ROM, DONE + LD A,MID_MDRAM ; MUST BE RAM +; +DSK_SELECT1A: + LD (MEDID),A +; +#ELSE ; ; DETERMINE MEDIA IN DRIVE LD A,(SEKUNIT) ; GET UNIT @@ -1234,11 +1242,48 @@ DSK_SELECT: LD E,1 ; ENABLE MEDIA CHECK/DISCOVERY RST 08 ; DO IT LD A,E ; RESULTANT MEDIA ID TO ACCUM + LD (MEDID),A ; SAVE IT OR A ; SET FLAGS LD HL,0 ; ASSUME FAILURE RET Z ; BAIL OUT IF NO MEDIA ; - ; A HAS MEDIA ID, SET HL TO CORRESPONDING DPBMAP ENTRY +#ENDIF +; + ; CLEAR LBA OFFSET (DWORD) + ; SET HI BIT FOR LBA ACCESS FOR NOW + LD HL,0 ; ZERO + LD (SEKLBA),HL ; CLEAR FIRST WORD + SET 7,H ; ASSUME LBA ACCESS FOR NOW + LD (SEKLBA+2),HL ; CLEAR SECOND WORD +; +#IFDEF PLTWBW +; + LD A,(SEKUNIT) ; GET UNIT + LD C,A ; STORE IN C + LD B,BF_DIODEVICE ; HBIOS FUNC: REPORT DEVICE INFO + RST 08 ; GET UNIT INFO, DEVICE TYPE IN D + LD A,D ; DEVICE TYPE -> A + AND $F0 ; ISOLATE HIGH BITS + CP DIODEV_FD ; FLOPPY? + JR NZ,DSK_SELECT1B ; IF NOT, DO LBA IO + LD HL,SEKLBA+3 ; POINT TO HIGH ORDER BYTE + RES 7,(HL) ; SWITCH FROM LBA -> CHS +; +#ENDIF +; +DSK_SELECT1B: + ; SET LEGACY SECTORS PER SLICE + LD HL,16640 ; LEGACY SECTORS PER SLICE + LD (SPS),HL ; SAVE IT +; + ; CHECK MBR OF PHYSICAL DISK BEING SELECTED + ; WILL UPDATE MEDID AND LBAOFF IF VALID CP/M PARTITION EXISTS + CALL DSK_MBR ; UPDATE MEDIA FROM MBR + LD HL,0 ; ASSUME FAILURE + RET NZ ; ABORT ON I/O ERROR +; + ; SET HL TO DPBMAP ENTRY CORRESPONDING TO MEDIA ID + LD A,(MEDID) ; GET MEDIA ID LD HL,DPBMAP ; HL = DPBMAP RLCA ; DPBMAP ENTRIES ARE 2 BYTES EACH CALL ADDHLA ; ADD OFFSET TO HL @@ -1247,21 +1292,169 @@ DSK_SELECT: LD E,(HL) ; DEREFERENCE HL... INC HL ; INTO DE... LD D,(HL) ; DE = ADDRESS OF DESIRED DPB -; +; ; PLUG DPB INTO THE ACTIVE DPH - LD HL,(SEKDPH) + LD HL,(SEKDPH) ; POINT TO START OF DPH LD BC,10 ; OFFSET OF DPB IN DPH ADD HL,BC ; HL := DPH.DPB LD (HL),E ; SET LSB OF DPB IN DPH INC HL ; BUMP TO MSB LD (HL),D ; SET MSB OF DPB IN DPH -#ENDIF +; + ; PLUG LBA OFFSET INTO ACTIVE DPH + LD HL,(SEKDPH) ; POINT TO START OF DPH + LD BC,16 ; OFFSET OF LBA OFFSET IN DPH + ADD HL,BC ; HL := DPH.LBAOFF PTR + EX DE,HL ; DEST IS DPH.LBAOFF PTR + LD HL,SEKLBA ; SOURCE IS LBAOFF + LD BC,4 ; 4 BYTES + LDIR ; DO IT ; DSK_SELECT2: LD HL,(SEKDPH) ; HL = DPH ADDRESS FOR CP/M XOR A ; FLAG SUCCESS RET ; NORMAL RETURN ; +; CHECK MBR OF DISK TO SEE IF IT HAS A PARTITION TABLE. +; IF SO, LOOK FOR A CP/M PARTITION. IF FOUND, GET +; UPDATE THE PARTITION OFFSET (LBAOFF) AND UPDATE +; THE MEDIA ID (MEDID). +; +DSK_MBR: + ; CHECK MEDIA TYPE, ONLY HARD DISK IS APPLICABLE + LD A,(MEDID) ; GET MEDIA ID + CP MID_HD ; HARD DISK? + JR Z,DSK_MBR0 ; IF SO, CONTINUE + XOR A ; ELSE, N/A, SIGNAL SUCCESS + RET ; AND RETURN + +DSK_MBR0: +; +#IFDEF PLTWBW + ; ACTIVATE BIOS BANK TO ACCESS DISK BUFFER + LD (STKSAV),SP ; SAVE CUR STACK + LD SP,STACK ; NEW STACK IN HI MEM + LD A,(BNKBIOS) ; ACTIVATE HBIOS BANK + PUSH IX ; SAVE IX + LD IX,DSK_MBR1 ; ROUTINE TO RUN + CALL HB_BNKCALL ; DO IT + POP IX ; RESTORE IX + LD SP,(STKSAV) ; RESTORE ORIGINAL STACK + RET +#ENDIF +; +DSK_MBR1: + ; FLUSH DSKBUF TO MAKE SURE IT IS SAFE TO USE IT. + CALL BLKFLSH ; MAKE SURE DISK BUFFER IS NOT DIRTY + XOR A ; CLEAR ACCUM + LD (HSTACT),A ; CLEAR HOST BUFFER ACTIVE FLAG +; + ; READ SECTOR ZERO (MBR) + LD B,BF_DIOREAD ; READ FUNCTION + LD A,(SEKUNIT) ; GET UNIT + LD C,A ; PUT IN C + LD DE,0 ; LBA SECTOR ZERO + LD HL,0 ; ... +#IFDEF PLTWBW + SET 7,D ; MAKE SURE LBA ACCESS BIT SET +#ENDIF + CALL DSK_IO2 ; DO IT + RET NZ ; ABORT ON ERROR +; + ; CHECK SIGNATURE + LD HL,(DSKBUF) ; DSKBUF ADR + LD DE,$1FE ; OFFSET TO SIGNATURE + ADD HL,DE ; POINT TO SIGNATURE + LD A,(HL) ; GET FIRST BYTE + CP $55 ; CHECK FIRST BYTE + JR NZ,DSK_MBR5 ; NO MATCH, NO PART TABLE + INC HL ; NEXT BYTE + LD A,(HL) ; GET SECOND BYTE + CP $AA ; CHECK SECOND BYTE + JR NZ,DSK_MBR5 ; NO MATCH, NO PART TABLE, ABORT +; + ; TRY TO FIND OUR ENTRY IN PART TABLE AND CAPTURE LBA OFFSET + LD B,4 ; FOUR ENTRIES IN PART TABLE + LD HL,(DSKBUF) ; DSKBUF ADR + LD DE,$1BE+4 ; OFFSET OF FIRST ENTRY PART TYPE + ADD HL,DE ; POINT TO IT +DSK_MBR2: + LD A,(HL) ; GET PART TYPE + CP $2E ; CP/M PARTITION? + JR Z,DSK_MBR3 ; COOL, GRAB THE LBA OFFSET + LD DE,16 ; PART TABLE ENTRY SIZE + ADD HL,DE ; BUMP TO NEXT ENTRY PART TYPE + DJNZ DSK_MBR2 ; LOOP THRU TABLE + JR DSK_MBR5 ; TOO BAD, NO CP/M PARTITION +; +DSK_MBR3: + ; WE HAVE LOCATED A VALID CP/M PARTITION + ; HL POINTS TO PART TYPE FIELD OF PART ENTRY +; + ; CAPTURE THE LBA OFFSET + LD DE,4 ; LBA IS 4 BYTES AFTER PART TYPE + ADD HL,DE ; POINT TO IT + LD DE,SEKLBA ; LOC TO STORE LBA OFFSET + LD BC,4 ; 4 BYTES (32 BITS) + LDIR ; COPY IT +; + ; CHECK THAT REQUESTED SLICE IS "INSIDE" PARTITION + ; SLICE SIZE IS EXACTLY 16,384 SECTORS (8MB), SO WE CAN JUST + ; RIGHT SHIFT PARTITION SECTOR COUNT BY 14 BITS + LD E,(HL) ; HL POINTS TO FIRST BYTE + INC HL ; ... OF 32 BIT PARTITION + LD D,(HL) ; ... SECTOR COUNT, + INC HL ; ... LOAD SECTOR COUNT + PUSH DE ; ... INTO DE:HL + LD E,(HL) ; ... + INC HL ; ... + LD D,(HL) ; ... + POP HL ; ... DE:HL = PART SIZE IN SECTORS + LD B,2 ; DE = DE:HL >> 2 (TRICKY!) + CALL RL32 ; DE = SLICECNT + EX DE,HL ; HL = SLICECNT + LD A,(SLICE) ; GET TARGET SLICE + LD C,A ; PUT IN C + LD B,0 ; BC := REQUESTED SLICE # + SCF ; SET CARRY! + SBC HL,BC ; MAX SLICES - SLICE - 1 + JR NC,DSK_MBR4 ; NO OVERFLOW, OK TO CONTINUE + OR $FF ; SLICE TOO HIGH, SIGNAL ERROR + RET ; AND BAIL OUT +; +DSK_MBR4: + ; IF BOOT FROM PARTITION, USE NEW SECTORS PER SLICE VALUE + LD HL,16384 ; NEW SECTORS PER SLICE + LD (SPS),HL ; SAVE IT + + ; UPDATE MEDIA ID + LD A,MID_HDNEW ; NEW MEDIA ID + LD (MEDID),A ; SAVE IT +; +DSK_MBR5: + ; ADJUST LBA OFFSET BASED ON TARGET SLICE + LD A,(SLICE) ; GET SLICE, A IS LOOP CNT + LD HL,(SEKLBA) ; SET DE:HL + LD DE,(SEKLBA+2) ; ... TO STARTING LBA + LD BC,(SPS) ; SECTORS PER SLICE +DSK_MBR6: + OR A ; SET FLAGS TO CHECK LOOP CNTR + JR Z,DSK_MBR8 ; DONE IF COUNTER EXHAUSTED + ADD HL,BC ; ADD ONE SLICE TO LOW WORD + JR NC,DSK_MBR7 ; CHECK FOR CARRY + INC DE ; IF SO, BUMP HIGH WORD +DSK_MBR7: + DEC A ; DEC LOOP DOWNCOUNTER + JR DSK_MBR6 ; AND LOOP +DSK_MBR8: + SET 7,D ; SET LBA ACCESS FLAG + ; RESAVE IT + LD (SEKLBA),HL ; LOWORD + LD (SEKLBA+2),DE ; HIWORD + ; SUCCESSFUL FINISH + XOR A ; SUCCESS + RET ; DONE +; ; ; DSK_STATUS: @@ -1272,7 +1465,7 @@ DSK_STATUS: ; C HAS CPM DRIVE, LOOKUP UNIT AND CHECK FOR INVALID DRIVE CALL DSK_GETINF ; B := UNIT RET NZ ; INVALID DRIVE ERROR - + ; VALID DRIVE, DISPATCH TO DRIVER LD C,D ; C := UNIT LD B,BF_DIOSTATUS ; B := FUNCTION: STATUS @@ -1296,71 +1489,18 @@ DSK_WRITE: ; ; ; -#IFDEF PLTUNA - -DSK_IO: - PUSH BC - LD DE,(HSTTRK) ; GET TRACK INTO HL - LD B,4 ; PREPARE TO LEFT SHIFT BY 4 BITS -DSK_IO1: - SLA E ; SHIFT DE LEFT BY 4 BITS - RL D - DJNZ DSK_IO1 ; LOOP TILL ALL BITS DONE - LD A,(HSTSEC) ; GET THE SECTOR INTO A - AND $0F ; GET RID OF TOP NIBBLE - OR E ; COMBINE WITH E - LD E,A ; BACK IN E - LD HL,0 ; HL:DE NOW HAS SLICE RELATIVE LBA - ; APPLY OFFSET NOW - ; OFFSET IS EXPRESSED AS NUMBER OF BLOCKS * 256 TO OFFSET! - LD A,(HSTOFF) ; LSB OF SLICE OFFSET TO A - ADD A,D ; ADD WITH D - LD D,A ; PUT IT BACK IN D - LD A,(HSTOFF+1) ; MSB OF SLICE OFFSET TO A - CALL ADCHLA ; ADD OFFSET - POP BC ; RECOVER FUNCTION IN B - LD A,(HSTUNIT) ; GET THE UNIT VALUE - LD C,A ; PUT IT IN C - ; DISPATCH TO DRIVER - PUSH BC - EX DE,HL ; DE:HL NOW HAS LBA - LD B,C ; UNIT TO B - LD C,$41 ; UNA SET LBA - RST 08 ; CALL UNA - CALL NZ,PANIC - POP BC ; RECOVER B=FUNC, C=UNIT - LD E,C ; UNIT TO E - LD C,B ; FUNC TO C - LD B,E ; UNIT TO B - LD DE,(DSKBUF) ; SET BUFFER ADDRESS - LD HL,1 ; 1 SECTOR - ; DISPATCH TO UBIOS - RST 08 - OR A ; SET FLAGS BASED ON RESULT - RET - -#ELSE - DSK_IO: -; -; TRANSLATE CP/M TRACK/SECTOR -> HBIOS TRACK/HEAD/SECTOR -; NEEDS TO HANDLE FLOPPY SEPARATE FROM HARD DISK -; -CHS: LD A,(HSTUNIT) ; GET UNIT LD C,A ; UNIT -> C - PUSH BC ; SAVE FUNC/UNIT - LD B,BF_DIODEVICE ; HBIOS FUNC: REPORT DEVICE INFO - RST 08 ; GET UNIT INFO, DEVICE TYPE IN D - POP BC ; GET FUNC/UNIT BACK TO BC - LD A,D ; DEVICE TYPE -> A - AND $F0 ; ISOLATE HIGH BITS - CP DIODEV_FD ; FLOPPY? - JR NZ,CHSHD ; IF NOT, DO HD CHS XLAT +; +#IFDEF PLTWBW + LD A,(HSTLBA+3) ; GET HIGH ORDER BYTE + BIT 7,A ; LBA ACCESS? + JR NZ,LBA_IO ; IF SET, GO TO LBA I/O ; ; FLOPPY SPECIFIC TRANSLATION ASSUMES FLOPPY IS DOUBLE-SIDED AND ; USES LOW ORDER BIT OF TRACK AS HEAD VALUE -; +; ; HBIOS SEEK: HL=CYLINDER, D=HEAD, E=SECTOR ; LD DE,(HSTSEC) ; SECTOR -> DE, HEAD(D) BECOMES ZERO @@ -1368,53 +1508,73 @@ CHS: SRL H ; SHIFT HEAD BIT OUT OF HL RR L ; ... AND INTO CARRY RL D ; CARRY BIT (HEAD) INTO D - JR CHS2 + JR DSK_IO2 ; DO THE DISK I/O ; -; HARD DISK SPECIFIC TRANSLATION -; ASSUMES 16 HEADS PER CYLINDER AND 16 SECTORS PER TRACK +#ENDIF ; -CHSHD: - LD HL,(HSTTRK) ; GET TRACK VALUE - LD A,L ; LSB OF TRACK TO A - AND $0F ; ISOLATE HEAD IN LOW 4 BITS - LD D,A ; STUFF IT IN D +LBA_IO: + PUSH BC ; SAVE FUNC/UNIT + ; GET TRACK AND SHIFT TO MAKE ROOM FOR 4 BIT SECTOR VALUE + LD HL,(HSTTRK) ; GET TRACK + LD DE,0 ; CLEAR HIWORD + LD B,4 ; X16 (16 SPT ASSUMED) + CALL RL32 ; DO IT + ; COMBINE WITH SECTOR LD A,(HSTSEC) ; GET SECTOR - LD E,A ; STUFF IT IN E - LD A,B ; SAVE B (HBIOS FUNC) - LD B,4 ; PREPARE TO SHIFT OUT 4 BIT HEAD VALUE -CHSHD1: - SRL H ; SHIFT ONE BIT OUT - RR L ; ... OF HL - DJNZ CHSHD1 ; DO ALL 4 BITS - LD B,A ; RESTORE B (HBIOS FUNC) - ; FALL THRU TO CHS2 -; -; ALL TYPES OF TRANSLATION WIND UP HERE TO -; MAKE THE ACTUAL HBIOS CALL -; -CHS2: - PUSH DE ; SAVE HEAD/SECTOR + COULD MOVE - LD DE,(HSTOFF) ; NOW GET SLICE OFFSET | TO CHSHD, - ADD HL,DE ; ADD IT TO TRACK VALUE | NO SLICES - POP DE ; RECOVER HEAD/SECTOR + FOR FLOPPY + OR L + LD L,A + ; ADD IN LBA OFFSET FOR PARTITION AND/OR SLICE + LD BC,(HSTLBA) ; LBA OFFSET LOWORD + ADD HL,BC + EX DE,HL + LD BC,(HSTLBA+2) ; LBA OFFSET HIWORD + ADC HL,BC + EX DE,HL + POP BC ; RESTORE FUNC/UNIT + ;JR DSK_IO2 ; DO THE DISK I/O (FALL THRU) +; +#IFDEF PLTUNA +; +; MAKE UNA UBIOS CALL +; HBIOS FUNC SHOULD STILL BE IN B +; UNIT SHOULD STILL BE IN C +; +DSK_IO2: + PUSH BC ; SAVE INCOMING FUNCTION, UNIT + LD B,C ; UNIT TO B + LD C,$41 ; UNA SET LBA + RST 08 ; CALL UNA + POP BC ; RECOVER B=FUNC, C=UNIT + RET NZ ; ABORT IF SEEK RETURNED AN ERROR W/ ERROR IN A + LD E,C ; UNIT TO E + LD C,B ; FUNC TO C + LD B,E ; UNIT TO B + LD DE,(DSKBUF) ; SET BUFFER ADDRESS + LD HL,1 ; 1 SECTOR + ; DISPATCH TO UBIOS + RST 08 ; CALL UNA + RET ; DONE +; +#ELSE ; ; MAKE HBIOS CALL ; HBIOS FUNC SHOULD STILL BE IN B ; UNIT SHOULD STILL BE IN C ; - PUSH BC ; SAVE INCOMING FUNCTION, DEVICE/UNIT - LD B,BF_DIOSEEK ; SETUP FOR NEW SEEK CALL +DSK_IO2: + PUSH BC ; SAVE INCOMING FUNCTION, UNIT + LD B,BF_DIOSEEK ; SETUP FOR NEW SEEK CALL RST 08 ; DO IT - POP BC ; RESTORE INCOMING FUNCTION, DEVICE/UNIT - RET NZ ; ABORT IF SEEK RETURNED AN ERROR W/ ERROR IN A - LD HL,(DSKBUF) ; GET BUFFER ADDRESS + POP BC ; RESTORE INCOMING FUNCTION, DEVICE/UNIT + RET NZ ; ABORT IF SEEK RETURNED AN ERROR W/ ERROR IN A + LD HL,(DSKBUF) ; GET BUFFER ADDRESS LD A,(BNKBIOS) ; GET BIOS BANK LD D,A ; TRANSFER TO/FROM BIOS BANK - LD E,1 ; TRANSFER ONE SECTOR + LD E,1 ; TRANSFER ONE SECTOR RST 08 ; DO IT OR A ; SET FLAGS RET ; DONE - +; #ENDIF ; ;================================================================================================== @@ -1501,12 +1661,16 @@ STR_SEC .DB " SEC=$" ; DATA ;================================================================================================== ; -;STR_READONLY .DB "\r\nCBIOS Err: Read Only Drive$" -;STR_STALE .DB "\r\nCBIOS Err: Stale Drive$" +;STR_READONLY .DB "\r\nCBIOS Err: Read Only Drive$" +;STR_STALE .DB "\r\nCBIOS Err: Stale Drive$" ; -SECADR .DW 0 ; ADDRESS OF SECTOR IN ROM/RAM PAGE +;SECADR .DW 0 ; ADDRESS OF SECTOR IN ROM/RAM PAGE DEFDRIVE .DB 0 ; DEFAULT DRIVE CCPBUF .DW 0 ; ADDRESS OF CCP BUF IN BIOS BANK +MEDID .DB 0 ; TEMP STORAGE FOR MEDIA ID +SLICE .DB 0 ; CURRENT SLICE +SPS .DW 0 ; SECTORS PER SLICE +STKSAV .DW 0 ; TEMP SAVED STACK POINTER ; #IFDEF PLTWBW BNKBIOS .DB 0 ; BIOS BANK ID @@ -1521,21 +1685,22 @@ BNKUSER .DW 0 ; USER BANK ID ; DOS DISK VARIABLES ; DSKOP .DB 0 ; DISK OPERATION (DOP_READ/DOP_WRITE) -WRTYPE .DB 0 ; WRITE TYPE (0=NORMAL, 1=DIR (FORCE), 2=FIRST RECORD OF BLOCK) -DMAADR .DW 0 ; DIRECT MEMORY ADDRESS +WRTYPE .DB 0 ; WRITE TYPE (0=NORMAL, 1=DIR (FORCE), 2=FIRST RECORD OF BLOCK) +DMAADR .DW 0 ; DIRECT MEMORY ADDRESS HSTWRT .DB 0 ; TRUE = BUFFER IS DIRTY DSKBUF .DW 0 ; ADDRESS OF PHYSICAL SECTOR BUFFER ; ; LOGICAL DISK I/O REQUEST PENDING ; SEK: -SEKDSK .DB 0 ; DISK NUMBER 0-15 -SEKTRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) -SEKSEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) -SEKUNIT .DB 0 ; DISK UNIT +SEKDSK .DB 0 ; DISK NUMBER 0-15 +SEKTRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) +SEKSEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) +SEKUNIT .DB 0 ; DISK UNIT SEKDPH .DW 0 ; ADDRESS OF ACTIVE (SELECTED) DPH SEKOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE SEKACT .DB TRUE ; ALWAYS TRUE! +SEKLBA .FILL 4,0 ; LBA OFFSET ; ; RESULT OF CPM TO PHYSICAL TRANSLATION ; @@ -1547,6 +1712,7 @@ XLTUNIT .DB 0 XLTDPH .DW 0 XLTOFF .DW 0 XLTACT .DB TRUE ; ALWAYS TRUE! +XLTLBA .FILL 4,0 ; LBA OFFSET ; XLTSIZ .EQU $ - XLT ; @@ -1560,13 +1726,14 @@ HSTUNIT .DB 0 ; DISK UNIT IN BUFFER HSTDPH .DW 0 ; CURRENT DPH ADDRESS HSTOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE HSTACT .DB 0 ; TRUE = BUFFER HAS VALID DATA +HSTLBA .FILL 4,0 ; LBA OFFSET ; ; SEQUENTIAL WRITE TRACKING FOR (UNA)LLOCATED BLOCK ; UNA: -UNADSK .DB 0 ; DISK NUMBER 0-15 -UNATRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) -UNASEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) +UNADSK .DB 0 ; DISK NUMBER 0-15 +UNATRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) +UNASEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) ; UNASIZ .EQU $ - UNA ; @@ -1595,13 +1762,13 @@ ALS_HD .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) ; BLS BSH BLM EXM (DSM<256) EXM (DSM>255) ; ---------- --- --- ------------- ------------- ; 1,024 3 7 0 N/A -; 2,048 4 15 1 0 -; 4,096 5 31 3 1 -; 8,192 6 63 7 3 -; 16,384 7 127 15 7 +; 2,048 4 15 1 0 +; 4,096 5 31 3 1 +; 8,192 6 63 7 3 +; 16,384 7 127 15 7 ; -; AL0/1: EACH BIT SET ALLOCATES A BLOCK OF DIR ENTRIES. EACH DIR ENTRY -; IS 32 BYTES. BIT COUNT = (((DRM + 1) * 32) / BLS) +; AL0/1: EACH BIT SET ALLOCATES A BLOCK OF DIR ENTRIES. EACH DIR ENTRY +; IS 32 BYTES. BIT COUNT = (((DRM + 1) * 32) / BLS) ; ; CKS = (DIR ENT / 4), ZERO FOR NON-REMOVABLE MEDIA ; @@ -1623,21 +1790,21 @@ ALS_HD .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) .DW ALS_ROM ; ALS: BLKS / 8 .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_ROM: - .DW 64 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK + .DW 64 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK .DB 1 ; EXM: (BLKS <= 256) ? 1 : 0 .DW 192 - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1 - .DW 255 ; DRM: DIR ENTRIES - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA - .DW 0 ; OFF: ROM DISK HAS NO SYSTEM AREA + .DW 255 ; DRM: DIR ENTRIES - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA + .DW 0 ; OFF: ROM DISK HAS NO SYSTEM AREA ;__________________________________________________________________________________________________ ; ; RAM DISK: 64 SECS/TRK, 128 BYTES/SEC ; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -; RAM DISK SIZE = TOTAL RAM - 128K RESERVED FOR SYSTEM USE +; RAM DISK SIZE = TOTAL RAM - 256K RESERVED FOR SYSTEM USE ; ; ALS_RAM, EXM, DSM MUST BE FILLED DYNAMICALLY: ; - ALS_RAM := (BANKS * 2) @@ -1650,16 +1817,16 @@ DPB_ROM: .DW ALS_RAM ; ALS: BLKS / 8 .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_RAM: - .DW 64 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK + .DW 64 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK .DB 1 ; EXM: (BLKS <= 256) ? 1 : 0 - .DW 192 - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1 - .DW 255 ; DRM: DIR ENTRIES - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA - .DW 0 ; OFF: RESERVED TRACKS = 0 TRK + .DW 128 - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1 + .DW 255 ; DRM: DIR ENTRIES - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA + .DW 0 ; OFF: RESERVED TRACKS = 0 TRK ;__________________________________________________________________________________________________ ; ; 4MB RAM FLOPPY DRIVE, 32 TRKS, 1024 SECS/TRK, 128 BYTES/SEC @@ -1669,16 +1836,16 @@ DPB_RAM: .DW ALS_HD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_RF: - .DW 64 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = (4MB / 2K BLS) - 1 = 2047 - .DW 511 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11111111B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA - .DW 0 ; OFF: RESERVED TRACKS = 0 TRK + .DW 64 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = (4MB / 2K BLS) - 1 = 2047 + .DW 511 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 + .DB 11111111B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA + .DW 0 ; OFF: RESERVED TRACKS = 0 TRK ;__________________________________________________________________________________________________ ; ; GENERIC HARD DISK DRIVE (8MB DATA SPACE + 128K RESERVED SPACE) @@ -1690,16 +1857,33 @@ DPB_RF: .DW ALS_HD .DB (4096 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_HD: - .DW 64 ; SPT: SECTORS PER TRACK - .DB 5 ; BSH: BLOCK SHIFT FACTOR - .DB 31 ; BLM: BLOCK MASK - .DB 1 ; EXM: EXTENT MASK - .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 = (8MB / 4K BLS) - 1 = 2047 - .DW 511 ; DRM: DIR ENTRIES - 1 = 512 - 1 = 511 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 16 ; OFF: RESERVED TRACKS = 16 TRKS * (16 TRKS * 16 HEADS * 16 SECS * 512 BYTES) = 128K + .DW 64 ; SPT: SECTORS PER TRACK + .DB 5 ; BSH: BLOCK SHIFT FACTOR + .DB 31 ; BLM: BLOCK MASK + .DB 1 ; EXM: EXTENT MASK + .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 = (8MB / 4K BLS) - 1 = 2047 + .DW 512 - 1 ; DRM: DIR ENTRIES - 1 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 16 ; OFF: RESERVED TRACKS +; +; BLOCKSIZE (BLS) = 4K, DIRECTORY ENTRIES = 1024 +; + .DW CKS_HD + .DW ALS_HD + .DB (4096 / 128) ; RECORDS PER BLOCK (BLS / 128) +DPB_HDNEW: + .DW 64 ; SPT: SECTORS PER TRACK + .DB 5 ; BSH: BLOCK SHIFT FACTOR + .DB 31 ; BLM: BLOCK MASK + .DB 1 ; EXM: EXTENT MASK + .DW 2048 - 1 - 4 ; DSM: STORAGE BLOCKS - 1 - RES TRKS + .DW 1024 - 1 ; DRM: DIR ENTRIES - 1 + .DB 11111111B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 2 ; OFF: RESERVED TRACKS ;__________________________________________________________________________________________________ ; ; IBM 720KB 3.5" FLOPPY DRIVE, 80 TRKS, 36 SECS/TRK, 512 BYTES/SEC @@ -1709,16 +1893,16 @@ DPB_HD: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD720: - .DW 36 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 350 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((720K - 18K OFF) / 2K BLS) - 1 = 350 - .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 - .DB 11000000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 - .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K + .DW 36 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 350 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((720K - 18K OFF) / 2K BLS) - 1 = 350 + .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 + .DB 11000000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 + .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K ;__________________________________________________________________________________________________ ; ; IBM 1.44MB 3.5" FLOPPY DRIVE, 80 TRKS, 72 SECS/TRK, 512 BYTES/SEC @@ -1728,16 +1912,16 @@ DPB_FD720: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD144: - .DW 72 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 710 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,440K - 18K OFF) / 2K BLS) - 1 = 710 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 72 SEC/TRK) = 18K + .DW 72 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 710 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,440K - 18K OFF) / 2K BLS) - 1 = 710 + .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 72 SEC/TRK) = 18K ;__________________________________________________________________________________________________ ; ; IBM 360KB 5.25" FLOPPY DRIVE, 40 TRKS, 9 SECS/TRK, 512 BYTES/SEC @@ -1747,16 +1931,16 @@ DPB_FD144: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD360: - .DW 36 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 1 ; EXM: EXTENT MASK - .DW 170 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((360K - 18K OFF) / 2K BLS) - 1 = 170 - .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 - .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K + .DW 36 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 1 ; EXM: EXTENT MASK + .DW 170 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((360K - 18K OFF) / 2K BLS) - 1 = 170 + .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 + .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K ;__________________________________________________________________________________________________ ; ; IBM 1.20MB 5.25" FLOPPY DRIVE, 80 TRKS, 15 SECS/TRK, 512 BYTES/SEC @@ -1766,16 +1950,16 @@ DPB_FD360: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD120: - .DW 60 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 591 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,200K - 15K OFF) / 2K BLS) - 1 = 591 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K + .DW 60 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 591 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,200K - 15K OFF) / 2K BLS) - 1 = 591 + .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K ;__________________________________________________________________________________________________ ; ; IBM 1.11MB 8" FLOPPY DRIVE, 77 TRKS, 15 SECS/TRK, 512 BYTES/SEC @@ -1785,16 +1969,16 @@ DPB_FD120: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD111: - .DW 60 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 569 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,155K - 15K OFF) / 2K BLS) - 1 = 569 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K + .DW 60 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 569 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,155K - 15K OFF) / 2K BLS) - 1 = 569 + .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K ; #IFDEF PLTUNA SECBUF .FILL 512,0 ; PHYSICAL DISK SECTOR BUFFER @@ -1846,12 +2030,12 @@ INIT: LD DE,(BNKBIOS) ; UBIOS_PAGE (SEE PAGES.INC) CALL $FFFD ; DO IT (RST 08 NOT YET INSTALLED) PUSH DE ; SAVE PREVIOUS BANK - + LD HL,0 ; FROM ADDRESS 0 (PAGE ZERO) LD DE,SECBUF ; USE SECBUF AS BOUNCE BUFFER LD BC,256 ; ONE PAGE IS 256 BYTES LDIR ; DO IT - + LD BC,$01FB ; UNA FUNC = SET BANK POP DE ; RECOVER OPERATING BANK CALL $FFFD ; DO IT (RST 08 NOT YET INSTALLED) @@ -1860,7 +2044,7 @@ INIT: LD DE,0 ; TO PAGE ZERO OF OPERATING BANK LD BC,256 ; ONE PAGE IS 256 BYTES LDIR ; DO IT - + ; INSTALL UNA INVOCATION VECTOR FOR RST 08 LD A,$C3 ; JP INSTRUCTION LD (8),A ; STORE AT 0x0008 @@ -1879,8 +2063,9 @@ INIT: ; SOFT RESET HBIOS LD B,BF_SYSRESET ; HB FUNC: RESET + LD C,BF_SYSRES_INT ; WARM START RST 08 ; DO IT - + ; CREATE A TEMP COPY OF THE HBIOS CONFIG BLOCK (HCB) ; FOR REFERENCE USE DURING INIT LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY @@ -1891,7 +2076,7 @@ INIT: LD HL,HCB_LOC ; COPY FROM FIXED LOCATION IN HB BANK LD DE,HCB ; TO TEMP LOCATION IN USR BANK RST 08 ; DO IT - + ; CAPTURE RAM DRIVE STARTING BANK LD A,(HCB + HCB_BIDRAMD0) LD (BNKRAMD),A @@ -1905,13 +2090,33 @@ INIT: CALL NEWLINE2 ; FORMATTING LD DE,STR_BANNER ; POINT TO BANNER CALL WRITESTR ; DISPLAY IT - + +#IFDEF PLTWBW + ; CHECK FPR HBIOS/CBIOS VERSION MISMATCH + LD B,BF_SYSVER ; HBIOS VERSION + RST 08 ; DO IT, DE=MAJ/MIN/UP/PAT + LD A,D ; A := MAJ/MIN + CP ((RMJ << 4) | RMN) ; MATCH? + JR NZ,INIT1 ; HANDLE VER MISMATCH + LD A,E ; A := OS UP/PAT + AND $F0 ; PAT NOT INCLUDED IN MATCH + CP (RUP << 4) ; MATCH? + JR NZ,INIT1 ; HANDLE VER MISMATCH + JR INIT2 ; ALL GOOD, CONTINUE +INIT1: + ; DISPLAY VERSION MISMATCH + CALL NEWLINE2 ; FORMATTING + LD DE,STR_VERMIS ; VERSION MISMATCH + CALL WRITESTR ; DISPLAY IT +INIT2: +#ENDIF +; #IFDEF PLTUNA ; SAVE COMMAND PROCESSOR IMAGE TO MALLOCED CACHE IN UNA BIOS PAGE LD C,$F7 ; UNA MALLOC LD DE,CCP_SIZ ; SIZE OF CCP RST 08 ; DO IT - CALL NZ,PANIC ; BIG PROBLEM + CALL NZ,ERR_BIOMEM ; BIG PROBLEM LD (CCPBUF),HL ; SAVE THE ADDRESS (IN BIOS MEM) LD BC,$01FB ; UNA FUNC = SET BANK @@ -1932,7 +2137,7 @@ INIT: LD B,BF_SYSALLOC ; HBIOS FUNC: ALLOCATE HEAP MEMORY LD HL,CCP_SIZ ; SIZE TO ALLOC (SIZE OF CCP) RST 08 ; DO IT - CALL NZ,PANIC ; BIG PROBLEM + CALL NZ,ERR_BIOMEM ; BIG PROBLEM LD (CCPBUF),HL ; SAVE THE ADDRESS (IN BIOS MEM) LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY LD A,(BNKUSER) ; GET USER BANK @@ -1978,7 +2183,7 @@ INIT: CALL PRTDEC ; PRINT IT LD DE,STR_MEMFREE ; ADD DESCRIPTION CALL WRITESTR ; AND PRINT IT -; +; LD A,(DEFDRIVE) ; GET DEFAULT DRIVE LD (CDISK),A ; ... AND SETUP CDISK ; @@ -1987,9 +2192,9 @@ INIT: LD DE,STR_CPM ; DEFAULT TO CP/M LABEL LD A,(BDOS_LOC) ; GET FIRST BYTE OF BDOS CP 'Z' ; IS IT A 'Z' (FOR ZSDOS)? - JR NZ,INIT2 ; NOPE, CP/M IS RIGHT + JR NZ,INIT3 ; NOPE, CP/M IS RIGHT LD DE,STR_ZSDOS ; SWITCH TO ZSDOS LABEL -INIT2: +INIT3: CALL WRITESTR ; DISPLAY OS LABEL LD DE,STR_TPA1 ; TPA PREFIX CALL WRITESTR @@ -1997,12 +2202,19 @@ INIT2: CALL PRTDECB ; PRINT IT CALL PC_PERIOD ; DECIMAL POINT LD A,0 + (((BDOS_LOC % 1024) * 100) / 1024) - CALL PRTDECB ; MANTISSA + CALL PRTDECB ; MANTISSA LD DE,STR_TPA2 ; AND TPA SUFFIX CALL WRITESTR CALL NEWLINE ; FORMATTING +; RET ; DONE ; +ERR_BIOMEM: + CALL NEWLINE2 ; FORMATTING + LD DE,STR_BIOMEM ; HBIOS HEAP MEM OVERFLOW + CALL WRITESTR ; TELL THE USER + CALL PANIC ; AND GRIND TO A SCREACHING HALT +; ; ;__________________________________________________________________________________________________ AUTOSUB: @@ -2045,7 +2257,7 @@ DEV_INIT: ; PATCH IN CRT: DEVICE LD A,(HCB + HCB_CRTDEV) ; GET CONSOLE DEVICE CP $FF ; NUL MEANS NO CRT DEVICE - JR Z,DEV_INIT00 ; IF SO, LEAVE IT ALONE + JR Z,DEV_INIT000 ; IF SO, LEAVE IT ALONE LD (DEVMAP + 1),A ; CONSOLE CRT LD (DEVMAP + 13),A ; LIST CRT ; @@ -2054,31 +2266,43 @@ DEV_INIT: LD B,A ; SAVE IN B LD A,(HCB + HCB_CONDEV) ; GET CONSOLE DEVICE CP B ; COMPARE - JR NZ,DEV_INIT00 ; IF DIFFERENT (CRT NOT ACTIVE), LEAVE IOBYTE ALONE + JR NZ,DEV_INIT000 ; IF DIFFERENT (CRT NOT ACTIVE), LEAVE IOBYTE ALONE LD A,1 ; IF SAME (CRT ACTIVE), SET IOBYTE FOR CON: = CRT: LD (IOBYTE),A ; STORE IN IOBYTE + LD HL,DEV_INIT1 ; INIT FIRST DEV ASSIGN ADR + JR DEV_INIT00 ; SKIP AHEAD +; +DEV_INIT000: + ; CONSOLE IS NOT THE CRT, SO + ; ASSIGN CURRENT CONSOLE AS TTY + LD A,(HCB + HCB_CONDEV) ; GET CONSOLE DEVICE + CALL DEV_INIT1 ; ASSIGN AS TTY ; DEV_INIT00: - ; LOOP THRU DEVICES ADDING NON-CRT DEVICES TO DEVMAP + ; LOOP THRU DEVICES ADDING DEVICES TO DEVMAP + ; CONSOLE DEVICE WAS ALREADY DONE, SO IT IS SKIPPED HERE LD B,BF_SYSGET ; HBIOS FUNC: GET SYS INFO LD C,BF_SYSGET_CIOCNT ; SUBFUNC: GET CIO UNIT COUNT RST 08 ; E := SERIAL UNIT COUNT LD B,E ; COUNT TO B LD C,0 ; UNIT INDEX - LD HL,DEV_INIT1 ; POINTER FOR FIRST ENTRY FOUND DEV_INIT0: - PUSH BC ; SAVE LOOP CONTROL - PUSH HL ; SAVE TARGET - LD B,BF_CIODEVICE ; HBIOS FUNC: GET DEVICE INFO - RST 08 ; D := DEVICE TYPE, E := PHYSICAL UNIT NUMBER - POP HL ; RESTORE TARGET - LD A,D ; DEVICE TYPE TO A - ; FIX: BELOW SHOULD TEST THE "TERMINAL" BIT INSTEAD OF CHECKING DEVICE NUMBER - CP CIODEV_TERM ; COMPARE TO FIRST VIDEO DEVICE - POP BC ; RESTORE LOOP CONTROL + ;PUSH BC ; SAVE LOOP CONTROL + ;PUSH HL ; SAVE TARGET + ;LD B,BF_CIODEVICE ; HBIOS FUNC: GET DEVICE INFO + ;RST 08 ; D := DEVICE TYPE, E := PHYSICAL UNIT NUMBER + ;POP HL ; RESTORE TARGET + ;LD A,D ; DEVICE TYPE TO A + ;; FIX: BELOW SHOULD TEST THE "TERMINAL" BIT INSTEAD OF CHECKING DEVICE NUMBER + ;CP CIODEV_TERM ; COMPARE TO FIRST VIDEO DEVICE + ;POP BC ; RESTORE LOOP CONTROL + ;LD A,C ; UNIT INDEX TO ACCUM + ;;CALL C,JPHL ; DO IT IF DEVICE TYPE < VDU + + LD A,(HCB + HCB_CONDEV) ; CURRENT CONSOLE UNIT + CP C ; IS CURRENT CONSOLE? LD A,C ; UNIT INDEX TO ACCUM - ;CALL C,JPHL ; DO IT IF DEVICE TYPE < VDU - CALL JPHL ; DO FOR ANY CHARACTER DEVICE TYPE + CALL NZ,JPHL ; DO IF NOT CURRENT CONSOLE INC C ; NEXT UNIT DJNZ DEV_INIT0 ; LOOP TILL DONE RET ; ALL DONE @@ -2131,10 +2355,12 @@ MD_INIT: ; #IFDEF PLTWBW LD A,(HCB + HCB_ROMBANKS) ; ROM BANK COUNT + SUB 4 ; REDUCE BANK COUNT BY RESERVED PAGES LD IX,DPB_ROM ; ADDRESS OF DPB CALL MD_INIT1 ; FIX IT UP ; LD A,(HCB + HCB_RAMBANKS) ; RAM BANK COUNT + SUB 8 ; REDUCE BANK COUNT BY RESERVED PAGES LD IX,DPB_RAM ; ADDRESS OF DPB CALL MD_INIT1 ; FIX IT UP ; @@ -2143,7 +2369,6 @@ MD_INIT: MD_INIT1: ; ; PUT USABLE BANK COUNT IN HL - SUB 4 ; REDUCE BANK COUNT BY RESERVED PAGES LD L,A ; PUT IN LSB OF HL LD H,0 ; MSB IS ALWAYS ZERO ; @@ -2510,7 +2735,7 @@ DRV_INIT3A: PUSH DE ; SAVE DE (HARD DISK VOLUME COUNTER) PUSH HL ; SAVE DRIVE LIST PTR PUSH BC ; SAVE LOOP CONTROL - + LD B,BF_DIOMEDIA ; HBIOS FUNC: SENSE MEDIA LD E,1 ; PERFORM MEDIA DISCOVERY RST 08 @@ -2518,9 +2743,9 @@ DRV_INIT3A: POP BC ; RESTORE LOOP CONTROL POP HL ; RESTORE DRIVE LIST PTR POP DE ; RESTORE DE - + RET NZ ; IF NO MEDIA, JUST RETURN - + ; IF ACTIVE... LD (HL),C ; SAVE UNIT NUM IN LIST INC HL ; BUMP PTR @@ -2638,7 +2863,8 @@ DPH_INIT: LD H,0 ; ... INTO HL ADD HL,HL ; MULTIPLY ADD HL,HL ; ... BY SIZE - ADD HL,HL ; ... OF DPH (16) + CALL ADDHLA ; ... + ADD HL,HL ; ... OF DPH (20) ADD HL,HL ; ... FOR TOTAL SIZE CALL ALLOC ; ALLOCATE THE SPACE CALL C,PANIC ; SHOULD NEVER ERROR @@ -2677,7 +2903,7 @@ DPH_INIT1: CALL PRTDRV ; PRINT DRIVE INFO LD A,D ; A := UNIT PUSH HL ; SAVE DRIVE MAP POINTER -DPH_INIT1A: +DPH_INIT1A: LD DE,(DPHTOP) ; GET ADDRESS OF NEXT DPH PUSH DE ; ... AND SAVE IT ; INVOKE THE DPH BUILD ROUTINE @@ -2695,7 +2921,8 @@ DPH_INIT2: LD (HL),D ; ... DRIVE MAP INC HL ; AND BUMP TO START OF NEXT ENTRY ; UPDATE DPH ALLOCATION TOP - LD A,16 ; SIZE OF A DPH ENTRY + ;LD A,16 ; SIZE OF A DPH ENTRY + LD A,20 ; SIZE OF A DPH ENTRY EX DE,HL ; HL := DPH POINTER CALL ADDHLA ; CALC NEW DPHTOP LD (DPHTOP),HL ; SAVE IT @@ -2776,7 +3003,7 @@ MAKDPH1: POP HL ; HL := START OF DPH LD A,8 ; SIZE OF DPH RESERVED AREA CALL ADDHLA ; LEAVE IT ALONE (ZERO FILLED) - + LD BC,(DIRBUF) ; ADDRESS OF DIRBUF LD (HL),C ; PLUG DIRBUF INC HL ; ... INTO DPH @@ -2813,7 +3040,7 @@ MAKDPH2: LD (HL),C ; SAVE CKS/ALS BUF INC HL ; ... ADDRESS IN LD (HL),B ; ... DPH AND BUMP - INC HL ; ... TO NEXT DPH ENTRY + INC HL ; ... TO NEXT DPH ENTRY XOR A ; SIGNAL SUCCESS RET ; @@ -2831,9 +3058,9 @@ ALLOC: EX DE,HL ; DE=NEW HEAPTOP, HL=HEAPLIM SBC HL,DE ; HEAPLIM - HEAPTOP JR C,ALLOCX ; C SET ON OVERFLOW ERROR - ; ALLOCATION SUCCEEDED, COMMIT NEW HEAPTOP + ; ALLOCATION SUCCEEDED, COMMIT NEW HEAPTOP LD (HEAPTOP),DE ; SAVE NEW HEAPTOP -ALLOCX: +ALLOCX: POP HL ; RETURN VALUE TO HL POP DE ; RECOVER DE RET @@ -2862,15 +3089,15 @@ PRTDRV: PUSH BC ; PRESERVE BC PUSH DE ; PRESERVE DE PUSH HL ; PRESERVE HL - + LD B,D ; B := UNIT LD C,$48 ; UNA FUNC: GET DISK TYPE CALL $FFFD ; CALL UNA LD A,D ; DISK TYPE TO A - + CP $40 JR Z,PRTDRV1 ; IF SO, HANDLE RAM/ROM - + LD DE,DEVIDE ; IDE STRING CP $41 ; IDE? JR Z,PRTDRVX ; IF YES, PRINT @@ -3011,15 +3238,17 @@ FCB_PRO .DB '?' ; DRIVE CODE, 0 = CURRENT DRIVE STR_BANNER .DB "CBIOS v", BIOSVER, " [", PLTSTR, "]$" STR_INITRAMDISK .DB "Formatting RAMDISK...$" STR_LDR2 .DB "\r\n" -STR_LDR .DB "\r\n $" +STR_LDR .DB "\r\n $" STR_DPHINIT .DB "Configuring Drives...$" STR_HEAPOVF .DB " *** Insufficient Memory ***$" STR_INVMED .DB " *** Invalid Device ID ***$" +STR_VERMIS .DB 7,"*** WARNING: HBIOS/CBIOS Version Mismatch ***$" STR_MEMFREE .DB " Disk Buffer Bytes Free$" STR_CPM .DB "CP/M-80 v2.2$" STR_ZSDOS .DB "ZSDOS v1.1$" STR_TPA1 .DB ", $" STR_TPA2 .DB "K TPA$" +STR_BIOMEM .DB "*** HBIOS Heap Overflow ***$" #IFDEF PLTUNA INIBUF .FILL 512,0 ; LOCATION OF TEMP WORK BUF DURING INIT (512 BYTES) diff --git a/Source/CBIOS/config.asm b/Source/CBIOS/config.asm index 1ad85aee..180feaeb 100644 --- a/Source/CBIOS/config.asm +++ b/Source/CBIOS/config.asm @@ -8,7 +8,7 @@ DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS CPM_LOC .EQU $D000 ; LOCATION OF START OF CCP ; #IFDEF PLTWBW -CPM_END .EQU $FE00 ; ROMWBW HBIOS PROXY OCCUPIES TOP 2 PAGES OF MEMORY +CPM_END .EQU $FE00 ; ROMWBW HBIOS PROXY OCCUPIES TOP $280 BYTES OF MEMORY #ENDIF ; #IFDEF PLTUNA diff --git a/Source/CBIOS/util.asm b/Source/CBIOS/util.asm index 023688ed..1d32990e 100644 --- a/Source/CBIOS/util.asm +++ b/Source/CBIOS/util.asm @@ -430,3 +430,15 @@ PRTHEXBUF1: INC DE DJNZ PRTHEXBUF1 RET +; +; LEFT SHIFT DE:HL BY B BITS (B > 0) +; +RL32: + OR A ; CLEAR CARRY + RL L + RL H + RL E + RL D + DJNZ RL32 + RET + diff --git a/Source/CPM3/Build.cmd b/Source/CPM3/Build.cmd index 1d0e1a9c..aa0c59c9 100644 --- a/Source/CPM3/Build.cmd +++ b/Source/CPM3/Build.cmd @@ -17,15 +17,16 @@ echo. echo *** CPM Loader *** echo. zx RMAC -CPMLDR +zx Z80ASM -UTIL/MF copy optdsk.lib ldropts.lib zx Z80ASM -BIOSLDR/MF move /Y biosldr.rel biosldrd.rel -zx LINK -CPMLDRD[L100]=CPMLDR,BIOSLDRD +zx LINK -CPMLDRD[L100]=CPMLDR,BIOSLDRD,UTIL move /Y cpmldrd.com cpmldr.bin copy optcmd.lib ldropts.lib zx Z80ASM -BIOSLDR/MF move /Y biosldr.rel biosldrc.rel -zx LINK -CPMLDRC[L100]=CPMLDR,BIOSLDRC +zx LINK -CPMLDRC[L100]=CPMLDR,BIOSLDRC,UTIL move /Y cpmldrc.com cpmldr.com rem pause @@ -101,3 +102,23 @@ rem Loader tasm -t80 -g3 -fFF loader.asm loader.bin loader.lst copy /b loader.bin + cpmldr.bin cpmldr.sys + +rem Copy OS files to Binary directory + +copy cpmldr.com ..\..\Binary\CPM3 +copy cpmldr.sys ..\..\Binary\CPM3 +copy ccp.com ..\..\Binary\CPM3 +copy gencpm.com ..\..\Binary\CPM3 +copy genres.dat ..\..\Binary\CPM3 +copy genbnk.dat ..\..\Binary\CPM3 +copy bios3.spr ..\..\Binary\CPM3 +copy bnkbios3.spr ..\..\Binary\CPM3 +copy bdos3.spr ..\..\Binary\CPM3 +copy bnkbdos3.spr ..\..\Binary\CPM3 +copy resbdos3.spr ..\..\Binary\CPM3 +copy cpm3res.sys ..\..\Binary\CPM3 +copy cpm3bnk.sys ..\..\Binary\CPM3 +copy gencpm.dat ..\..\Binary\CPM3 +copy cpm3.sys ..\..\Binary\CPM3 +copy readme.1st ..\..\Binary\CPM3 +copy cpm3fix.pat ..\..\Binary\CPM3 \ No newline at end of file diff --git a/Source/CPM3/Makefile b/Source/CPM3/Makefile index 4eb2a352..46c6bc32 100644 --- a/Source/CPM3/Makefile +++ b/Source/CPM3/Makefile @@ -4,11 +4,19 @@ # # it does this by overriding OBJECTS in an invoked sub-make # -OBJECTS = cpmldr.com cpmldr.sys cpm3res cpm3bnk zpmbios3 cpm3.sys gencpm.dat -OTHERS = cpmldr.rel biosldr.rel cpm3res.sys cpm3bnk.sys zpmbios3.spr loader.bin cpmldr.bin +OBJECTS = cpmldr.com cpmldr.sys cpm3res.sys cpm3bnk.sys zpmbios3 +OBJECTS += ccp.com gencpm.com genres.dat genbnk.dat +OBJECTS += bdos3.spr bnkbdos3.spr resbdos3.spr +OBJECTS += readme.1st cpm3fix.pat cpm3.sys gencpm.dat +NOCOPY = zpmbios3 +OTHERS = cpmldr.rel biosldr.rel cpm3res.sys cpm3bnk.sys loader.bin cpmldr.bin OTHERS += biosldrc.rel biosldrd.rel +NODELETE = ccp.com gencpm.com genres.dat genbnk.dat bdos3.spr bnkbdos3.spr resbdos3.spr +NODELETE += readme.1st cpm3fix.pat +DEST = ../../Binary/CPM3 TOOLS = ../../Tools + include $(TOOLS)/Makefile.inc export ZXINCDIR = ../ @@ -25,11 +33,11 @@ DEFCPM3 = bnk clean:: biosclean @rm -f bios3.spr bnkbios3.spr zpmbios3.spr cpmldr.com gencpm.dat options.lib ldropts.lib - + biosclean: @rm -f $(BIOSOBJS) -cpm3res: +cpm3res.sys: make biosclean cp optres.lib options.lib cp genres.dat gencpm.dat @@ -38,7 +46,7 @@ cpm3res: mv cpm3.sys cpm3res.sys rm gencpm.dat -cpm3bnk: +cpm3bnk.sys: make biosclean cp optbnk.lib options.lib cp genbnk.dat gencpm.dat @@ -50,16 +58,14 @@ cpm3bnk: zpmbios3: make biosclean cp optzpm.lib options.lib - cp genbnk.dat gencpm.dat - make OBJECTS=zpmbios3.spr - rm gencpm.dat + make OBJECTS=zpmbios3.spr DEST= -cpmldr.bin: biosldrd.rel cpmldr.rel - $(ZXCC) $(TOOLS)/cpm/bin/LINK -CPMLDRD[L100]=CPMLDR,BIOSLDRD +cpmldr.bin: biosldrd.rel cpmldr.rel util.rel + $(ZXCC) $(TOOLS)/cpm/bin/LINK -CPMLDRD[L100]=CPMLDR,BIOSLDRD,UTIL mv cpmldrd.com cpmldr.bin -cpmldr.com: biosldrc.rel cpmldr.rel - $(ZXCC) $(TOOLS)/cpm/bin/LINK -CPMLDRC[L100]=CPMLDR,BIOSLDRC +cpmldr.com: biosldrc.rel cpmldr.rel util.rel + $(ZXCC) $(TOOLS)/cpm/bin/LINK -CPMLDRC[L100]=CPMLDR,BIOSLDRC,UTIL mv cpmldrc.com cpmldr.com biosldrc.rel: biosldr.z80 optcmd.lib @@ -89,3 +95,4 @@ gencpm.dat: gen$(DEFCPM3).dat cpmldr.sys: loader.bin cpmldr.bin cat loader.bin cpmldr.bin > $@ + diff --git a/Source/CPM3/bioskrnl.asm b/Source/CPM3/bioskrnl.asm index ab3a9ccd..bd21c783 100644 --- a/Source/CPM3/bioskrnl.asm +++ b/Source/CPM3/bioskrnl.asm @@ -507,6 +507,11 @@ seldsk: mov a,m ! inx h ! mov h,m ! mov l,a ; get address of LOGIN routine call ipchl ; call LOGIN pop h ; recover DPH pointer + ; WBW Start + ora a + rz ; successful return + lxi h,0 ; error occurred, clear HL + ; WBW End not$first$select: ret diff --git a/Source/CPM3/biosldr.z80 b/Source/CPM3/biosldr.z80 index 9fc960d3..86083212 100644 --- a/Source/CPM3/biosldr.z80 +++ b/Source/CPM3/biosldr.z80 @@ -4,6 +4,12 @@ maclib cpm3.lib cseg + + extrn phex16, phex8 + extrn cin, cout + extrn crlf, crlf2 + + debug equ false ; BIOS Jump vector. @@ -51,109 +57,211 @@ jp 0 ; reserved for future expansion jp 0 ; reserved for future expansion -boot: - - if cmdline +mbrsec equ dtabuf +boot: + ; The main module (cpmldr.asm) does not expect the + ; boot call to use much stack. We use our own during + ; this routine to avoid issues. ld (stksav),sp ld sp,stack - -boot1: - ld de,msgunit - call writestr - call cin - push af - call cout - pop af - sub '0' - ld (unit),a - jr c,selerr - - ld bc,0F810h ; HBIOS, get disk unit count - call 0FFF0h ; do it, E := disk unit count - ld a,(unit) ; get unit num back - cp e ; compare to entry - jr nc,selerr ; loop if too high + ; Do the real work + call boot0 - ld de,msgslc - call writestr - call cin - push af - call cout - pop af - - sub '0' - ld (slice),a - jr c,selerr - cp 10 - jr nc,selerr + ; Restore original stack and return + ld sp,(stksav) + ret - jr boot2 +boot0: + + if cmdline + +boot1: + ; Get disk unit from user + ld de,msgunit ; disk unit prompt + call writestr ; display on console + call cin ; get a character + push af ; save it + call cout ; echo character + pop af ; restore it + sub '0' ; convert to binary + ld (unit),a ; save it + jr c,selerr ; loop if below 0 entered + ld bc,0F810h ; HBIOS, get disk unit count + call 0FFF0h ; do it, E := disk unit count + ld a,(unit) ; get unit num back + cp e ; compare to entry + jr nc,selerr ; loop if too high + + ; Get disk slice from user + ld de,msgslc ; slice prompt + call writestr ; display on console + call cin ; get a character + push af ; save it + call cout ; echo it + pop af ; restore it + sub '0' ; convert to binary + ld (slice),a ; save it + jr c,selerr ; loop if below 0 entered + cp 10 ; check for over 9 + jr nc,selerr ; loop if over 9 + ld de,msgcrlf ; linefeed + call writestr ; ... to console + jr boot2 ; boot w/ unit & slice selerr: - ld de,msginv - call writestr - jr boot1 + ; Display invalid entry message and restart + ld de,msginv ; error message + call writestr ; display on console + jr boot1 ; loop boot2: - ld de,crlf - call writestr - - ld sp,(stksav) + ; Record unit & slice w/ HBIOS + ld bc,0F9E0h ; HBIOS func: set boot info + ld a,(unit) ; get unit + ld d,a ; put in D + ld a,(slice) ; get slice + ld e,a ; put in E + ld l,0 ; Bank is always zero + call 0FFF0h ; do it - ld bc,0F9E0h ; HBIOS func: set boot info - ld a,(unit) ; get unit - ld d,a ; put in D - ld a,(slice) ; get slice - ld e,a ; put in E - ld l,0 ; Bank is always zero - call 0FFF0h ; do it - else - - ld bc,0F8E0h ; HBIOS func: get boot info - call 0FFF0h ; do it, D := boot unit, E: := slice - ld a,d ; move unit to A - ld (unit),a ; save it - ld a,e ; move slice to A - ld (slice),a ; save it + + ; Get unit & slice from HBIOS + ld bc,0F8E0h ; HBIOS func: get boot info + call 0FFF0h ; do it, D := boot unit, E: := slice + ld a,d ; move unit to A + ld (unit),a ; save it + ld a,e ; move slice to A + ld (slice),a ; save it endif - ld a,(unit) ; Get boot unit - ld c,a ; put in C - ld b,18h ; HBIOS Media function - ld e,1 ; Enable media check/discovery - call 0FFF0H ; HBIOS call - ld a,e ; Resultant media id to accum - or a ; Set flags - ;halt - ; - ; !!! Need to do something on error !!! - ; - ret z ; Bail out on error - + ; Check that drive actually exists + ld bc,0F810h ; HBIOS func: get disk count + call 0FFF0h ; do it, E=disk count + ld a,(unit) ; get boot disk unit + cp e ; compare to count + jp nc,err_nodisk ; handle no disk err + + ; Sense media to determine media format + ld a,(unit) ; Get boot unit + ld c,a ; put in C + ld b,18h ; HBIOS Media function + ld e,1 ; Enable media check/discovery + call 0FFF0H ; HBIOS call + jp nz,err_diskio ; handle error + ld a,e ; resultant media id to accum + ld (medid),a ; save media id + or a ; set flags, 0 is no media + jp z,err_diskio ; handle no media error + + ; Initialize slice start LBA & sectors per slice + ld hl,0 ; assume slice starts + ld (lba),hl ; ... at LBA offset + ld (lba+2),hl ; ... of zero + ld hl,16640 ; assume legacy value for + ld (sps),hl ; ... sectors per slice + + ; If not hard disk, skip partition & slice stuff + ld a,(medid) ; get media id + cp 4 ; hard disk? + jr nz,boot9 ; if not, jump ahead + + ; Read MBR + ld de,8000h ; LBA address zero + ld hl,0 ; ... to read first sector + ld bc,mbrsec ; read into MBR buffer + ld (dma),bc ; save + ld b,1 ; one sector + ld a,(unit) ; get bootunit + ld c,a ; put in C + call diskread ; do it, no return on err + + ; Check signature + ld hl,(mbrsec+1FEh) ; get signature + ld a,l ; first byte + cp 055h ; should be $55 + jr nz,boot5 ; if not, no part table + ld a,h ; second byte + cp 0AAh ; should be $AA + jr nz,boot5 ; if not, no part table + + ; Search part table for CP/M entry (type 0x2E) + ld b,4 ; four entries in part table + ld hl,mbrsec+1BEh+4 ; offset of first part type +boot3: + ld a,(hl) ; get part type + cp 2Eh ; CP/M partition? + jr z,boot4 ; cool, grab the LBA offset + ld de,16 ; part table entry size + add hl,de ; bump to next part type + djnz boot3 ; loop thru table + jr boot5 ; too bad, no CP/M partition + +boot4: + ; Capture the starting LBA of the CP/M partition we found + ld de,4 ; LBA is 4 bytes after part type + add hl,de ; point to it + ld de,lba ; loc to store lba offset + ld bc,4 ; 4 bytes (32 bits) + ldir ; copy it + + ; For now, it is implied that a slice within a partition + ; table will be in the "new" disk format. So, we now + ; adjust the sectors per slice and media id. + + ; Use new slice format sectors per slice value + ld hl,16384 ; new sectors per slice + ld (sps),hl ; save it + + ; Update media id for new hard disk format + ld a,10 ; new media id + ld (medid),a ; save it + +boot5: + ; Adjust LBA offset based on target slice + ld a,(slice) ; get boot slice, A is loop cnt + ld hl,(lba) ; set DE:HL + ld de,(lba+2) ; ... to starting LBA + ld bc,(sps) ; sectors per slice +boot6: + or a ; set flags to check loop cntr + jr z,boot8 ; done if counter exhausted + add hl,bc ; add one slice to low word + jr nc,boot7 ; check for carry + inc de ; if so, bump high word +boot7: + dec a ; dec loop downcounter + jr boot6 ; and loop +boot8: + ld (lba),hl ; save new lba, low word + ld (lba+2),de ; save new lba, high word + +boot9: + ; Locate DPB corresponding to media id ld hl,dpb$start - dpb$sz ld de,dpb$sz - ld b,a ; loop count -dsk$login1: - add hl,de ; next dpb - djnz dsk$login1 ; loop as needed - - ; hl is ptr to desired dpb - ld de,dph0 ; load DPH pointer - ex de,hl ; de = DPB adr, hl = DPH adr - push de ; save DPB adr - ld de,12 ; offset of DPB in DPH - add hl,de ; hl = adr of DPB field in DPH - pop de ; recover DPB adr - ld (hl),e ; update LSB - inc hl - ld (hl),d ; udpate MSB + ld a,(medid) ; get media id + ld b,a ; to loop count +boot10: + add hl,de ; next dpb + djnz boot10 ; loop as needed + + ; Stuff DPB ptr (HL) into DPH + ld de,dph0 ; load DPH pointer + ex de,hl ; de = DPB adr, hl = DPH adr + push de ; save DPB adr + ld de,12 ; offset of DPB in DPH + add hl,de ; hl = adr of DPB field in DPH + pop de ; recover DPB adr + ld (hl),e ; update LSB + inc hl ; point to MSB + ld (hl),d ; update MSB + + ret ; done - ret - wboot: ld a,81H halt @@ -162,15 +270,14 @@ const: ld a,82H halt conin: - ld bc,0080H ; unit 80h (console), func 0 = CIN - call 0FFF0H - + ld bc,0080h ; unit 80h (console), func 0 = CIN + call 0FFF0h ; do it + ld a,e ; put in C + ret ; done conout: - ld e,c ; output character in E - ld bc,0180H ; unit 80h (console), func 1 = COUT - ;rst 08 ; do it - call 0FFF0H - ret ; return + ld e,c ; output character in E + ld bc,0180h ; unit 80h (console), func 1 = COUT + jp 0FFF0h list: ld a,85H halt @@ -195,63 +302,122 @@ setsec: ld (sect),bc ret setdma: + + if debug + + push hl + push bc + pop hl + call crlf + call phex16 + pop hl + + endif + ld (dma),bc ret + read: - ld a,(unit) ; get unit - ld c,a ; BIOS Disk Unit in C - ld b,12H ; HBIOS SEEK function - push bc ; save it - ;push de ; save XDPH pointer - ld b,17h ; HBIOS DEVICE function - rst 08 ; Do it, D=device type - ld a,d ; put in accum - and 0F0h ; isolate high bits - ld b,1 ; assume it is floppy, 1 head bit - ld c,01h ; 1 bit head mask - cp 10h ; floppy? - jr z,seek0 ; yup, skip ahead - ld b,4 ; must be hard disk, 4 head bits - ld c,0Fh ; 4 bit head mask -seek0: - ;pop de ; recover XDPH pointer - push bc ; save bc - ld a,(slice) ; get slice - ld e,a ; slice to E - ld h,65 ; number of tracks per slice - call mult8 ; HL now has track offset for slice - pop bc ; recover bc - push hl ; save track offset for now - ld hl,(trk) ; get track value - ld a,l ; lsb of track to a - and c ; apply mask - ld d,a ; save in d -seek1: - srl h ; shift one bit out - rr l ; ... of hl - djnz seek1 ; do all bits - ld a,(sect) ; get sector - ld e,a ; stuff it in e - ex de,hl ; de=track, hl=head/sect - ex (sp),hl ; save head/sect, hl = offset - add hl,de ; hl has final track value - pop de ; recover head/sect to de - pop bc ; recover function & unit - ;rst 08 ; perform seek - call 0FFF0H - - ; Read Sector - ld b,13h ; HBIOS read - ld a,(unit) ; get boot unit - ld c,a ; put in C - ld hl,(dma) ; dma address - ld a,(0FFE0H) ; current bank - ld d,a ; ... to D - ld e,1 ; 1 sector - ;rst 08 - call 0FFF0H + if debug + + call crlf + ld a,(unit) + call phex8 + ld a,' ' + call cout + ld hl,(trk) + call phex16 + ld a,' ' + call cout + ld hl,(sect) + call phex16 + ld a,' ' + call cout + ld hl,(lba+2) + call phex16 + ld hl,(lba+0) + call phex16 - ret + endif + + ; Check device type + ld a,(unit) ; get unit + ld c,a ; BIOS Disk Unit in C + ld b,17h ; HBIOS DEVICE function + rst 08 ; Do it, D=device type + ld a,d ; put in accum + and 0F0h ; isolate high bits + cp 10h ; floppy? + jr nz,read2 ; if not, do LBA i/o + + ; Floppy I/O + ld de,(sect) ; sector -> de, head(d) becomes zero + ld hl,(trk) ; track -> hl (low bit has head) + srl h ; shift head bit out of hl + rr l ; ... and into carry + rl d ; carry bit (head) into d + jr read3 ; do the disk i/o + + ; LBA I/O +read2: + ld hl,(trk) ; get track + ld de,0 ; clear hiword + ld b,4 ; x16 (16 spt assumed) + call rl32 ; do it + ; combine with sector + ld a,(sect) ; get sector + or l ; combine + ld l,a ; and back to L + ; add in lba offset + ld bc,(lba) ; lba offset loword + add hl,bc ; add to cur loword + ex de,hl ; swap + ld bc,(lba+2) ; lba offset hiword + adc hl,bc ; add w/ carry to cur hiword + ex de,hl ; swap back + set 7,d ; set lba access bit + +read3: + + if debug + + ld a,' ' + call cout + ex de,hl + call phex16 + ex de,hl + call phex16 + + endif + + ; DE:HL has sector address to read (LBA or CHS) + ld a,(unit) ; get disk unit + ld c,a ; put in C + ld b,1 ; read 1 sector + jr diskread ; read sector and return + +diskread: + ; Read disk sector(s) + ; DE:HL is LBA, B is sector count, C is disk unit + + ; Seek to requested sector in DE:HL + push bc ; save unit & count + ld b,012h ; HBIOS func: seek + call 0FFF0h ; do it + pop bc ; recover unit & count + jp nz,err_diskio ; handle error + + ; Read sector(s) into buffer + ld e,b ; transfer count + ld b,013h ; HBIOS func: disk read + ld hl,(dma) ; read into info sec buffer + ld a,(0FFE0h) ; get current bank + ld d,a ; put in D + call 0FFF0h ; do it + jp nz,err_diskio ; handle error + xor a ; signal success + ret ; and done + write: ld a,8EH halt @@ -291,10 +457,11 @@ flush: halt move: - ex de,hl ; we are passed source in DE and dest in HL - ldir ; use Z80 block move instruction - ex de,hl ; need next addresses in same regs - ret + ; On input, DE=src, HL=dest + ex de,hl ; swap HL/DE for LDIR + ldir ; Z80 block move + ex de,hl ; swap back (required!) + ret ; done time: ld a,9AH halt @@ -307,22 +474,21 @@ setbnk: xmove: ld a,9DH halt - -cin: - ; input character from console via hbios - ld c,080H ; console unit to c - ld b,00H ; hbios func: input char - call 0FFF0H ; hbios reads character - ld a,e ; move character to a for return - ret -cout: - ; output character to console via hbios - ld e,a ; output char to e - ld c,080H ; console unit to c - ld b,01H ; hbios func: output char - call 0FFF0H ; hbios outputs character - ret +;cin: +; ; Input character from console via HBIOS +; ld c,080H ; console unit to C +; ld b,00H ; HBIOS func: input char +; call 0FFF0H ; HBIOS reads character +; ld a,e ; To A for return +; ret ; done + +;cout: +; ; Output character to console via HBIOS +; ld e,a ; output char to E +; ld c,080H ; console unit to C +; ld b,01H ; HBIOS func: output char +; jp 0FFF0H ; output & return writestr: push af @@ -339,153 +505,190 @@ writestr2: pop af ret -; -; 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 +rl32: + ; Left shift DE:HL by B bits (B > 0) + or a ; clear carry + rl l ; rotate L thru carry + rl h ; rotate H thru carry + rl e ; rotate E thru carry + rl d ; rotate D thru carry + djnz rl32 ; loop B times + ret ; done + +err_nodisk: + ld hl,str_err_nodisk + jr err +err_noslice: + ld hl,str_err_noslice + jr err +err_diskio: + ld hl,str_err_diskio + jr err +err_sig: + ld hl,str_err_sig + jr err +err_api: + ld hl,str_err_api + jr err +err: + push hl + ld de,str_err_prefix + call writestr + pop de + call writestr + halt + +str_err_prefix db "\r\n\r\n*** ","$" +str_err_nodisk db "Disk unit not available","$" +str_err_noslice db "Disk unit does not support slices","$" +str_err_diskio db "Disk I/O failure","$" +str_err_sig db "No system image on disk","$" +str_err_api db "HBIOS API failure","$" msgunit db 13,10,13,10,'Boot CP/M 3 from Disk Unit: $' msgslc db ' Slice: $' msginv db 13,10,13,10,'*** Invalid Selection ***$' -crlf db 13,10,'$' +msgcrlf db 13,10,'$' dpb$start: dpb$rom: ; 384K ROM Drive - dw 64 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 1 ; exm: extent mask - dw 192 - 1 ; dsm: total storage in blocks - 1 = (384kb / 2k bls) - 1 = 191 - dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H - dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k + dw 64 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 1 ; exm: extent mask + dw 192 - 1 ; dsm: total storage in blocks - 1 = (384kb / 2k bls) - 1 = 191 + dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb$sz equ $ - dpb$start dpb$ram: ; 256K RAM Drive - dw 64 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 1 ; exm: extent mask - dw 128 - 1 ; dsm: total storage in blocks - 1 = (256kb / 2k bls) - 1 = 127 - dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H - dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k + dw 64 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 1 ; exm: extent mask + dw 128 - 1 ; dsm: total storage in blocks - 1 = (256kb / 2k bls) - 1 = 127 + dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb$rf: ; 4MB RAM Floppy Drive - dw 64 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 2047 ; dsm: total storage in blocks - 1 = (4mb / 2k bls) - 1 = 2047 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H - dw 0 ; off: reserved tracks = 0 trks + dw 64 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 2047 ; dsm: total storage in blocks - 1 = (4mb / 2k bls) - 1 = 2047 + dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 0 ; off: reserved tracks = 0 trks db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb$hd: ; 8MB Hard Disk Drive - dw 64 ; spt: sectors per track - db 5 ; bsh: block shift factor - db 31 ; blm: block mask - db 1 ; exm: extent mask - dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 - dw 511 ; drm: dir entries - 1 = 512 - 1 = 511 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H - dw 16 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k + dw 64 ; spt: sectors per track + db 5 ; bsh: block shift factor + db 31 ; blm: block mask + db 1 ; exm: extent mask + dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 + dw 512-1 ; drm: dir entries - 1 = 512 - 1 = 511 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 16 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb$fd720: ; 3.5" DS/DD Floppy Drive (720K) - dw 36 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 350 ; dsm: total storage in blocks - 1 blk = ((720k - 18k off) / 2k bls) - 1 = 350 - dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 - db 11000000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 32 ; cks: directory check vector size = 128 / 4 - dw 4 ; off: reserved tracks = 4 trks * (512 b/sec * 36 sec/trk) = 18k + dw 36 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 350 ; dsm: total storage in blocks - 1 blk = ((720k - 18k off) / 2k bls) - 1 = 350 + dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 + db 11000000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 32 ; cks: directory check vector size = 128 / 4 + dw 4 ; off: reserved tracks = 4 trks * (512 b/sec * 36 sec/trk) = 18k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb_fd144: ; 3.5" DS/HD Floppy Drive (1.44M) - dw 72 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 710 ; dsm: total storage in blocks - 1 blk = ((1,440k - 18k off) / 2k bls) - 1 = 710 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 64 ; cks: directory check vector size = 256 / 4 - dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 72 sec/trk) = 18k + dw 72 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 710 ; dsm: total storage in blocks - 1 blk = ((1,440k - 18k off) / 2k bls) - 1 = 710 + dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 64 ; cks: directory check vector size = 256 / 4 + dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 72 sec/trk) = 18k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 -dpb_fd360: ; 5.25" DS/DD Floppy Drive (360K) - dw 36 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 1 ; exm: extent mask - dw 170 ; dsm: total storage in blocks - 1 blk = ((360k - 18k off) / 2k bls) - 1 = 170 - dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 32 ; cks: directory check vector size = 128 / 4 - dw 4 ; off: reserved tracks = 4 trks * (512 b/sec * 36 sec/trk) = 18k +dpb_fd360: ; 5.25" DS/DD Floppy Drive (360K) + dw 36 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 1 ; exm: extent mask + dw 170 ; dsm: total storage in blocks - 1 blk = ((360k - 18k off) / 2k bls) - 1 = 170 + dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 32 ; cks: directory check vector size = 128 / 4 + dw 4 ; off: reserved tracks = 4 trks * (512 b/sec * 36 sec/trk) = 18k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb_fd120: ; 5.25" DS/HD Floppy Drive (1.2M) - dw 60 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 591 ; dsm: total storage in blocks - 1 blk = ((1,200k - 15k off) / 2k bls) - 1 = 591 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 64 ; cks: directory check vector size = 256 / 4 - dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 60 sec/trk) = 15k + dw 60 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 591 ; dsm: total storage in blocks - 1 blk = ((1,200k - 15k off) / 2k bls) - 1 = 591 + dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 64 ; cks: directory check vector size = 256 / 4 + dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 60 sec/trk) = 15k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb_fd111: ; 8" DS/DD Floppy Drive (1.11M) - dw 60 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 569 ; dsm: total storage in blocks - 1 blk = ((1,155k - 15k off) / 2k bls) - 1 = 569 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 64 ; cks: directory check vector size = 256 / 4 - dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 60 sec/trk) = 15k + dw 60 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 569 ; dsm: total storage in blocks - 1 blk = ((1,155k - 15k off) / 2k bls) - 1 = 569 + dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 64 ; cks: directory check vector size = 256 / 4 + dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 60 sec/trk) = 15k + db 2 ; psh: 2 for 512 byte sectors + db 3 ; phm: (512 / 128) - 1 + +dpb$hdnew: ; 8MB Hard Disk Drive (new format) + dw 64 ; spt: sectors per track + db 5 ; bsh: block shift factor + db 31 ; blm: block mask + db 1 ; exm: extent mask + dw 2048 - 1 - 4 ; dsm: total storage in blocks - 1 = 2048 - 1 - resvd tracks + dw 1024 - 1 ; drm: dir entries + db 11111111b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 2 ; off: reserved tracks db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 @@ -493,13 +696,13 @@ dph0: dw 0 ; xlt, 0 means no translation db 0,0,0,0,0,0,0,0,0 ; scratch (9 bytes) db 0 ; mf: media flag dw dpb$hd ; dpb - dw csvbuf ; csv: - dw alvbuf ; alv: + dw csvbuf ; csv: + dw alvbuf ; alv: dw dirbcb ; dirbcb dw dtabcb ; dtabcb dw 0ffffh ; hash (disabled) db 0 ; hbank - + dtbl: dtbl dph0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dirbcb: db 0ffh ; drv @@ -524,13 +727,32 @@ trk ds 2 ; current track sect ds 2 ; current sector dma ds 2 ; current DMA address -csvbuf ds 128 ; length (CSV) = ((DRM+1)/4) -alvbuf ds 512 ; length (ALV) = ((DSM+1)/4) -dirbuf ds 512 ; sector buffer -dtabuf ds 512 ; sector buffer +medid ds 1 ; media id +lba ds 4 ; current lba +sps ds 2 ; sectors per slice ds 64 stack equ $ -stksav dw 0 +stksav ds 2 + +csvbufs equ 256 +alvbufs equ 512 +dirbufs equ 512 +dtabufs equ 512 + +;csvbuf ds 256 ; length (CSV) = ((DRM+1)/4) +;alvbuf ds 512 ; length (ALV) = ((DSM+1)/4) +;dirbuf ds 512 ; sector buffer +;dtabuf ds 512 ; sector buffer + +; Trying to save space. The loader must fit underneath +; the start of BNKBDOS3 and we have a big BNKBDOS because +; of all the disk allocations. Putting these buffers +; in upper memory actually helps quite a bit. + +csvbuf equ 8000h +alvbuf equ csvbuf + csvbufs +dirbuf equ alvbuf + alvbufs +dtabuf equ dirbuf + dirbufs end diff --git a/Source/CPM3/boot.z80 b/Source/CPM3/boot.z80 index 53e36f47..0b9c42f7 100644 --- a/Source/CPM3/boot.z80 +++ b/Source/CPM3/boot.z80 @@ -14,9 +14,12 @@ extrn @date,@hour,@min,@sec extrn @srch1 extrn @hbbio - extrn addhla, bcd2bin, bin2bcd - extrn cout, phex8, phex16, crlf, crlf2 - + extrn addhla + ;extrn phex16, phex8 + ;extrn cin, cout + ;extrn crlf, crlf2 + extrn bcd2bin, bin2bcd + include c:ver.lib bdos equ 5 @@ -41,7 +44,7 @@ tpa$bank equ 0 if banked ; Clone page zero from bank 0 to additional banks - ld b,3 ; last bank + ld b,4 ; last bank ld c,0 ; src bank init$2: push bc ; save bank id's @@ -59,6 +62,23 @@ init$2: ld hl,signon$msg ; signon message call ?pmsg ; print it + ; Check for HBIOS/CBIOS mismatch + ld b,0F1h ; hbios version + rst 08 ; do it, de=maj/min/up/pat + ld a,d ; a := maj/min + cp ((rmj << 4) | rmn) ; match? + jr nz,init$3 ; handle ver mismatch + ld a,e ; a := os up/pat + and 0F0h ; pat not included in match + cp (rup << 4) ; match? + jr nz,init$3 ; handle ver mismatch + jr init$4 ; all good, continue +init$3: + ; display version mismatch + ld hl,vermis$msg ; version mismatch + call ?pmsg ; display it +init$4: + ; Get boot disk unit and save it ld bc,0F8E0h ; HBIOS func: get boot info rst 08 ; do it, D := boot unit, E: := boot slice @@ -228,25 +248,26 @@ dinit6: pop de ; restore drive list ptr inc de ; increment active drive list ptr djnz dinit6 ; loop as needed + ret - ; zero out remaining dph table entries - ld a,16 ; dph table entries - sub l ; subtract entries used - ret z ; return if all entries used - ld b,a ; save as loop counter - ld a,l ; current dph to accum - rlca ; *2 for word entry - ld hl,@dtbl ; start of dtbl - call addhla ; hl now points to entry - -dinit6a: - xor a ; zero accum - ld (hl),a ; zero lsb - inc hl ; next byte - ld (hl),a ; zero msb - inc hl ; next byte - djnz dinit6a - ret ; finished +; ; zero out remaining dph table entries +; ld a,16 ; dph table entries +; sub l ; subtract entries used +; ret z ; return if all entries used +; ld b,a ; save as loop counter +; ld a,l ; current dph to accum +; rlca ; *2 for word entry +; ld hl,@dtbl ; start of dtbl +; call addhla ; hl now points to entry +; +;dinit6a: +; xor a ; zero accum +; ld (hl),a ; zero lsb +; inc hl ; next byte +; ld (hl),a ; zero msb +; inc hl ; next byte +; djnz dinit6a +; ret ; finished dinit7: ; process a unit (all slices) ld e,0 ; initialize slice index @@ -380,18 +401,18 @@ fill: ?ldccp: ; Force CCP to use system boot drive as initial default - ld a,(@sysdr) ; get system boot drive - ld (@ccpdr),a ; set CCP current drive + ;ld a,(@sysdr) ; get system boot drive + ;ld (@ccpdr),a ; set CCP current drive ; First time, load the CCP.COM file into TPA - ld a,(@sysdr) ; get system boot drive - ;ld (4),a ; save in page zero??? - inc a ; drive + 1 for FCB - ld (ccp$fcb),a ; stuff into FCB - add 'A' - 1 ; drive letter - ld (ccp$msg$drv),a ; save for load msg - xor a - ld (ccp$fcb+15),a + ;ld a,(@sysdr) ; get system boot drive + ;;ld (4),a ; save in page zero??? + ;inc a ; drive + 1 for FCB + ;ld (ccp$fcb),a ; stuff into FCB + ;add 'A' - 1 ; drive letter + ;ld (ccp$msg$drv),a ; save for load msg + ;xor a + ;ld (ccp$fcb+15),a ld hl,0 ld (fcb$nr),hl ld de,ccp$fcb @@ -670,6 +691,7 @@ read: clrflg db 0 ; RAM disk cleared flag clr$msg db 'RAM Disk Initialized',13,10,13,10,0 +vermis$msg db 7,'*** WARNING: HBIOS/CBIOS Version Mismatch ***',13,10,13,10,0 if zpm @@ -677,16 +699,16 @@ signon$msg db 13,10,'ZPM3' if banked db ' [BANKED]' endif - db ' on HBIOS v' + db ' for HBIOS v' biosver db 13,10,13,10,0 ccp$msg db 13,10,'BIOS Err on ' -ccp$msg$drv db '?' +ccp$msg$drv db 'A' db ': No ZCCP.COM file',0 -ccp$fcb db 0,'ZCCP ','COM',0,0,0,0 +ccp$fcb db 1,'ZCCP ','COM',0,0,0,0 ds 16 fcb$nr db 0,0,0 @@ -696,16 +718,16 @@ signon$msg db 13,10,'CP/M v3.0' if banked db ' [BANKED]' endif - db ' on HBIOS v' + db ' for HBIOS v' biosver db 13,10,13,10,0 ccp$msg db 13,10,'BIOS Err on ' -ccp$msg$drv db '?' +ccp$msg$drv db 'A' db ': No CCP.COM file',0 -ccp$fcb db 0,'CCP ','COM',0,0,0,0 +ccp$fcb db 1,'CCP ','COM',0,0,0,0 ds 16 fcb$nr db 0,0,0 diff --git a/Source/CPM3/diskio.z80 b/Source/CPM3/diskio.z80 index 154d601d..90c0eb1c 100644 --- a/Source/CPM3/diskio.z80 +++ b/Source/CPM3/diskio.z80 @@ -37,7 +37,7 @@ extrn ?bnkxlt - ;extrn phex8, cout + extrn phex8, cout ; CP/M 3 Disk definition macros @@ -60,113 +60,129 @@ bell equ 7 dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph0: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph1: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph2: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph3: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph4: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph5: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph6: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph7: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph8: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph9: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph10: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph11: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph12: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph13: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph14: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read dw dsk$login dw dsk$init - db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) + db 0FFh,0FFh ; HBIOS Disk Unit/Slice (filled in at boot) dph15: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset cseg ; DPB must be resident @@ -175,11 +191,12 @@ dpb$max: db 5 ; bsh: block shift factor db 31 ; blm: block mask db 1 ; exm: extent mask - dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 - dw 511 ; drm: dir entries - 1 = 512 - 1 = 511 - db 11110000b ; al0: dir blk bit map, first byte + dw 2048 - 1 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 + dw 1024 - 1 ; drm: dir entries - 1 + db 11111111b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte - dw 64 ; cks: directory check vector size - 256 / 4 + ;dw 64 ; cks: directory check vector size - 256 / 4 + dw 256 ; cks: directory check vector size - 1024 / 4 dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 @@ -194,7 +211,7 @@ dpb$rom: ; 384K ROM Drive dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 8040h ; cks: directory check vector size - permanent storage = 8000H dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 @@ -209,7 +226,7 @@ dpb$ram: ; 256K RAM Drive dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 8040h ; cks: directory check vector size - permanent storage = 8000H dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 @@ -219,25 +236,25 @@ dpb$rf: ; 4MB RAM Floppy Drive db 4 ; bsh: block shift factor db 15 ; blm: block mask db 0 ; exm: extent mask - dw 2047 ; dsm: total storage in blocks - 1 = (4mb / 2k bls) - 1 = 2047 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + dw 2048 - 1 ; dsm: total storage in blocks - 1 = (4mb / 2k bls) - 1 = 2047 + dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 8040h ; cks: directory check vector size - permanent storage = 8000H dw 0 ; off: reserved tracks = 0 trks db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 -dpb$hd: ; 8MB Hard Disk Drive +dpb$hd: ; 8MB Hard Disk Drive w/ 512 dir entries dw 64 ; spt: sectors per track db 5 ; bsh: block shift factor db 31 ; blm: block mask db 1 ; exm: extent mask - dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 - dw 511 ; drm: dir entries - 1 = 512 - 1 = 511 + dw 2048 - 1 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 + dw 512 - 1 ; drm: dir entries - 1 = 512 - 1 = 511 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 8080h ; cks: directory check vector size - permanent storage = 8000H dw 16 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 @@ -247,8 +264,8 @@ dpb$fd720: ; 3.5" DS/DD Floppy Drive (720K) db 4 ; bsh: block shift factor db 15 ; blm: block mask db 0 ; exm: extent mask - dw 350 ; dsm: total storage in blocks - 1 blk = ((720k - 18k off) / 2k bls) - 1 = 350 - dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 + dw 351 - 1 ; dsm: total storage in blocks - 1 blk = ((720k - 18k off) / 2k bls) - 1 = 350 + dw 128 - 1 ; drm: dir entries - 1 = 128 - 1 = 127 db 11000000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte dw 32 ; cks: directory check vector size = 128 / 4 @@ -261,8 +278,8 @@ dpb_fd144: ; 3.5" DS/HD Floppy Drive (1.44M) db 4 ; bsh: block shift factor db 15 ; blm: block mask db 0 ; exm: extent mask - dw 710 ; dsm: total storage in blocks - 1 blk = ((1,440k - 18k off) / 2k bls) - 1 = 710 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + dw 711 - 1 ; dsm: total storage in blocks - 1 blk = ((1,440k - 18k off) / 2k bls) - 1 = 710 + dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte dw 64 ; cks: directory check vector size = 256 / 4 @@ -275,8 +292,8 @@ dpb_fd360: ; 5.25" DS/DD Floppy Drive (360K) db 4 ; bsh: block shift factor db 15 ; blm: block mask db 1 ; exm: extent mask - dw 170 ; dsm: total storage in blocks - 1 blk = ((360k - 18k off) / 2k bls) - 1 = 170 - dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 + dw 171 - 1 ; dsm: total storage in blocks - 1 blk = ((360k - 18k off) / 2k bls) - 1 = 170 + dw 128 - 1 ; drm: dir entries - 1 = 128 - 1 = 127 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte dw 32 ; cks: directory check vector size = 128 / 4 @@ -289,8 +306,8 @@ dpb_fd120: ; 5.25" DS/HD Floppy Drive (1.2M) db 4 ; bsh: block shift factor db 15 ; blm: block mask db 0 ; exm: extent mask - dw 591 ; dsm: total storage in blocks - 1 blk = ((1,200k - 15k off) / 2k bls) - 1 = 591 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + dw 592 - 1 ; dsm: total storage in blocks - 1 blk = ((1,200k - 15k off) / 2k bls) - 1 = 591 + dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte dw 64 ; cks: directory check vector size = 256 / 4 @@ -303,8 +320,8 @@ dpb_fd111: ; 8" DS/DD Floppy Drive (1.11M) db 4 ; bsh: block shift factor db 15 ; blm: block mask db 0 ; exm: extent mask - dw 569 ; dsm: total storage in blocks - 1 blk = ((1,155k - 15k off) / 2k bls) - 1 = 569 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + dw 570 - 1 ; dsm: total storage in blocks - 1 blk = ((1,155k - 15k off) / 2k bls) - 1 = 569 + dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte dw 64 ; cks: directory check vector size = 256 / 4 @@ -312,6 +329,20 @@ dpb_fd111: ; 8" DS/DD Floppy Drive (1.11M) db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 +dpb$hdnew: ; 8MB Hard Disk Drive (new format) + dw 64 ; spt: sectors per track + db 5 ; bsh: block shift factor + db 31 ; blm: block mask + db 1 ; exm: extent mask + dw 2048 - 1 - 4 ; dsm: total storage in blocks - 1 = 2048 - 1 - resvd tracks + dw 1024 - 1 ; drm: dir entries + db 11111111b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8100h ; cks: directory check vector size - permanent storage = 8000H + dw 2 ; off: reserved tracks + db 2 ; psh: 2 for 512 byte sectors + db 3 ; phm: (512 / 128) - 1 + dseg ; rest is banked @@ -370,48 +401,191 @@ dsk$login: ;ld a,'L' ;call cout + + ld (curdph),de ; save working DPH + ex de,hl ; DPH adr to HL + dec hl ; point to slice + ld a,(hl) ; get slice + ld (slice),a ; save it + dec hl ; point to disk unit + ld a,(hl) ; get unit + ld (unit),a ; save it + inc a ; 0FFh -> 000h + jp z,err_ret ; bail out on no disk mapped here + + ;call media ; update DPH for media + ;ret - push de ; save DPH ptr +media: + ; Set retry address + ld hl,media + ld (retry$adr),hl - ; check media - ld a,(@rdrv) ; get disk unit - ;halt - ld c,a ; put in C - ld b,18h ; HBIOS Media function - ld e,1 ; Enable media check/discovery - ;rst 08 - call 0FFF0H ; HBIOS call - ld a,e ; Resultant media id to accum - or a ; Set flags - ;halt - ; - ; !!! Need to do something on error !!! - ; - jr nz,dsk$login0 ; continue if OK - pop de ; else error - ret ; return + ; Sense media to determine media format + ld a,(unit) ; get disk unit + ld c,a ; put in C + ld b,18h ; HBIOS Media function + ld e,1 ; Enable media check/discovery + call 0FFF0H ; HBIOS call + jp nz,err_diskio ; handle error + ld a,e ; resultant media id to accum + ld (medid),a ; save media id + or a ; set flags, 0 is no media + jp z,err_nodisk ; handle no media error + + ; Initialize slice start LBA & sectors per slice + ld hl,0 ; assume slice starts + ld (lba),hl ; ... at LBA offset + set 7,h ; ... of zero + ld (lba+2),hl ; ... w/ LBA access + + ; Check device type + ld a,(unit) ; get disk unit + ld c,a ; put in C + ld b,17h ; HBIOS func: report device info + call 0FFF0h ; get unit info, device type in D + ld a,d ; device type -> A + and 0F0h ; isolate high bits + cp 10h ; floppy? + jr nz,media1 ; if not, do LBA I/O + ld hl,lba+3 ; point to high order byte + res 7,(hl) ; switch from LBA -> CHS + +media1: + ld hl,16640 ; assume legacy value for + ld (sps),hl ; ... sectors per slice + + ; If not hard disk, skip partition & slice stuff + ld a,(medid) ; get media id + cp 4 ; hard disk? + jp nz,media9 ; if not, jump ahead + + ; Read MBR + ld de,8000h ; LBA address zero + ld hl,0 ; ... to read first sector + ld bc,mbrsec ; read into MBR buffer + ld (dma),bc ; save + ld a,(0FFE0h) ; get current HBIOS bank + ld (bank),a ; set DMA bank + ld a,(unit) ; get bootunit + ld c,a ; put in C + ld b,013h ; HBIOS func: disk read + call dsk$io ; do it + ret nz ; abort on error + + ; Check signature + ld hl,(mbrsec+1FEh) ; get signature + ld a,l ; first byte + cp 055h ; should be $55 + jr nz,media5 ; if not, no part table + ld a,h ; second byte + cp 0AAh ; should be $AA + jr nz,media5 ; if not, no part table + + ; Search part table for CP/M entry (type 0x2E) + ld b,4 ; four entries in part table + ld hl,mbrsec+1BEh+4 ; offset of first part type +media3: + ld a,(hl) ; get part type + cp 2Eh ; CP/M partition? + jr z,media4 ; cool, grab the LBA offset + ld de,16 ; part table entry size + add hl,de ; bump to next part type + djnz media3 ; loop thru table + jr media5 ; too bad, no CP/M partition + +media4: + ; Capture the starting LBA of the CP/M partition we found + ld de,4 ; LBA is 4 bytes after part type + add hl,de ; point to it + ld de,lba ; loc to store lba offset + ld bc,4 ; 4 bytes (32 bits) + ldir ; copy it -dsk$login0: + ; Check that requested slice is "inside" partition. + ; Slice size is exactly 16,384 sectors (8mb), so we can just + ; right shift partition sector count by 14 bits + ld e,(hl) ; HL points to first byte + inc hl ; ... of 32 bit partition + ld d,(hl) ; ... sector count, + inc hl ; ... load sector count + push de ; ... into DE:HL + ld e,(hl) ; ... + inc hl ; ... + ld d,(hl) ; ... + pop hl ; ... DE:HL = part size in sectors + ld b,2 ; DE = DE:HL >> 2 (tricky!) + call rl32 ; DE = slicecnt + ex de,hl ; HL = slicecnt + ld a,(slice) ; get target slice + ld c,a ; put in C + ld b,0 ; BC := requested slice # + scf ; set carry! + sbc hl,bc ; max slices - slice - 1 + jp c,err_noslice ; slice too high, error exit + + ; For now, it is implied that a slice within a partition + ; table will be in the "new" disk format. So, we now + ; adjust the sectors per slice and media id. + + ; Use new slice format sectors per slice value + ld hl,16384 ; new sectors per slice + ld (sps),hl ; save it + + ; Update media id for new hard disk format + ld a,10 ; new media id + ld (medid),a ; save it + +media5: + ; Adjust LBA offset based on target slice + ld a,(slice) ; get slice, A is loop cnt + ld hl,(lba) ; set DE:HL + ld de,(lba+2) ; ... to starting LBA + ld bc,(sps) ; sectors per slice +boot6: + or a ; set flags to check loop cntr + jr z,boot8 ; done if counter exhausted + add hl,bc ; add one slice to low word + jr nc,boot7 ; check for carry + inc de ; if so, bump high word +boot7: + dec a ; dec loop downcounter + jr boot6 ; and loop +boot8: + set 7,d ; set LBA access flag + ld (lba),hl ; save new lba, low word + ld (lba+2),de ; save new lba, high word + +media9: + ; Locate DPB corresponding to media id ld hl,dpb$start - dpb$sz ld de,dpb$sz - ld b,a ; loop count -dsk$login1: - add hl,de ; next dpb - djnz dsk$login1 ; loop as needed - - ; hl is ptr to desired dpb - pop de ; restore DPH ptr - ;halt - ex de,hl ; de = DPB adr, hl = DPH adr - push de ; save DPB adr - ld de,12 ; offset of DPB in DPH - add hl,de ; hl = adr of DPB field in DPH - pop de ; recover DPB adr - ld (hl),e ; update LSB - inc hl - ld (hl),d ; udpate MSB - ret ; done - + ld a,(medid) ; get media id + ld b,a ; to loop count +media10: + add hl,de ; next dpb + djnz media10 ; loop as needed + + ; Stuff DPB ptr (HL) and LBA offset into DPH + ; DPH: DPB @ +12, LBA @ +25 + ld de,(curdph) ; load DPH pointer + ex de,hl ; de = DPB adr, hl = DPH adr + push de ; save DPB adr + ld de,12 ; offset of DPB in DPH + add hl,de ; hl = adr of DPB field in DPH + pop de ; recover DPB adr + ld (hl),e ; update LSB + inc hl ; point to MSB + ld (hl),d ; update MSB + ld de,12 ; 12 more bytes to LBA + add hl,de ; HL points to LBA offset field + ld de,lba ; DE points to LBA offset + ex de,hl ; swap for copy + ld bc,4 ; 4 bytes + ldir ; do it + + xor a ; signal success + ret ; done ; disk READ and WRITE entry points. @@ -429,116 +603,115 @@ dsk$login1: ; if necessary, then return an error code in dsk$read: -; ld ix,30H -; halt + ld a,13h ; HBIOS disk read function + ld (func),a ; save it + jr dsk$rw ; common disk read/write code - ;ld a,'R' - ;call cout +dsk$write: + ld a,14h ; HBIOS disk write function + ld (func),a ; save it + jr dsk$rw ; common disk read/write code - push de ; save XDPH pointer - call dsk$seek ; disk seek - pop hl ; restore pointer to HL - ret nz ; abort on seek error -; - dec hl ; point to unit field of XDPH - dec hl - ld c,(hl) ; BIOS Disk Unit in C - ld b,13H ; HBIOS READ function - ld hl,(@dma) ; Dest buffer adr +dsk$rw: + ; Common disk read/write routine + ; Assumes func is set to HBIOS read or write + + ; Set retry address + ld hl,dsk$rw$retry + ld (retry$adr),hl + + ; Save XDPH address + ld (curdph),de ; save to curdph + +dsk$rw$retry: + ; Get LBA offset from DPH to DE:HL + ld hl,(curdph) ; HL := DPH adr + ld de,25 ; LBA value adr + add hl,de ; HL := LBA offset + ld e,(hl) ; lobyte of loword + inc hl ; bump + ld d,(hl) ; hibyte of loword + inc hl ; bump + push de ; save loword + ld e,(hl) ; lobyte of hiword + inc hl ; bump + ld d,(hl) ; hibyte of hiword + pop hl ; recover loword + + bit 7,d ; LBA access bit set? + jr nz,dsk$rw2 ; if so, go to LBA I/O + + ; Floppy I/O + ld de,(@sect) ; sector -> de, head(d) becomes zero + ld hl,(@trk) ; track -> hl (low bit has head) + srl h ; shift head bit out of hl + rr l ; ... and into carry + rl d ; carry bit (head) into d + jr dsk$rw9 ; do the disk I/O + +dsk$rw2: + ; LBA I/O + push de ; save hiword of LBA + push hl ; save loword of LBA + + ; Get track and shift into correct bits + ld hl,(@trk) ; get track + ld de,0 ; clear hiword + ld b,4 ; x16 (16 spt assumed) + call rl32 ; do it + + ; Combine with sector + ld a,(@sect) ; get sector + or l ; combine + ld l,a ; and back to L + + ; Add in LBA offset + pop bc ; lba offset loword + add hl,bc ; add to cur loword + ex de,hl ; swap + pop bc ; lba offset hiword + adc hl,bc ; add w/ carry to cur hiword + ex de,hl ; swap back + +dsk$rw9: + ; DE:HL has sector address to read (LBA or CHS) + ld bc,(@dma) ; get dma address + ld (dma),bc ; save for dsk$io if banked - ld a,(@dbnk) ; destination bank - call ?bnkxlt + ld a,(@dbnk) ; destination bank + call ?bnkxlt ; xlat to HBIOS else - ld a,(0FFE0H) ; get current bank + ld a,(0FFE0H) ; get current bank endif - ld d,a ; set desk bank - ld e,1 ; 1 sector - rst 08 ; do it - ;call 0FFF0H - - ;call phex8 - ret ; return + ld (bank),a + ld a,(func) ; get HBIOS func code + ld b,a ; put in B + ld a,(@rdrv) ; get disk unit + ld c,a ; put in C + ;jr dsk$io ; fall thru to dsk$io! + +dsk$io: + ; Read/write a disk sector + ; DE:HL is CHS/LBA, B is HBIOS func, C is disk unit + + ; Seek to requested sector in DE:HL + push bc ; save func & unit + ld b,012h ; HBIOS func: seek + call 0FFF0h ; do it + pop bc ; recover func & unit + jp nz,err_diskio ; handle error + + ; Read sector(s) into buffer + ld e,1 ; transfer count + ld hl,(dma) ; read into info sec buffer + ld a,(bank) ; HBIOS DMA bank + ld d,a ; put in D + call 0FFF0h ; do it + jp nz,err_diskio ; handle error + xor a ; signal success + ret ; and done -; lxi h,read$msg ; point at " Read " -; mvi a,88h ! mvi b,01h ; 1797 read + Z80DMA direction -; jmp rw$common -dsk$write: - ;ld ix,32H - ;halt - - push de ; save XDPH pointer - call dsk$seek ; disk seek - pop hl ; restore pointer to XDPH - ret nz ; abort on seek error -; - dec hl ; point to unit field of XDPH - dec hl - ld c,(hl) ; BIOS Disk Unit in C - ld b,14H ; HBIOS WRITE function - ld hl,(@dma) ; Dest buffer adr - if banked - ld a,(@dbnk) ; destination bank - call ?bnkxlt - else - ld a,(0FFE0H) ; get current bank - endif - ld d,a ; set desk bank - ld e,1 ; 1 sector - rst 08 ; do it - ;call 0FFF0H - ret ; return - -; lxi h,write$msg ; point at " Write " -; mvi a,0A8h ! mvi b,05h ; 1797 write + Z80DMA direction -; ; jmp wr$common - -dsk$seek: - dec de ; point to unit field of XDPH - dec de - ld a,(de) ; get it - ld c,a ; BIOS Disk Unit in C - ld b,12H ; HBIOS SEEK function - push bc ; save it - push de ; save XDPH pointer - ld b,17h ; HBIOS DEVICE function - rst 08 ; Do it, D=device type - ld a,d ; put in accum - and 0F0h ; isolate high bits - ld b,1 ; assume it is floppy, 1 head bit - ld c,01h ; 1 bit head mask - cp 10h ; floppy? - jr z,seek0 ; yup, skip ahead - ld b,4 ; must be hard disk, 4 head bits - ld c,0Fh ; 4 bit head mask -seek0: - pop de ; recover XDPH pointer - push bc ; save bc - inc de ; point to slice field of XDPH - ld a,(de) ; get it - ld e,a ; slice to E - ld h,65 ; number of tracks per slice - call mult8 ; HL now has track offset for slice - pop bc ; recover bc - push hl ; save track offset for now - ld hl,(@trk) ; get track value - ld a,l ; lsb of track to a - and c ; apply mask - ld d,a ; save in d -seek1: - srl h ; shift one bit out - rr l ; ... of hl - djnz seek1 ; do all bits - ld a,(@sect) ; get sector - ld e,a ; stuff it in e - ex de,hl ; de=track, hl=head/sect - ex (sp),hl ; save head/sect, hl = offset - add hl,de ; hl has final track value - pop de ; recover head/sect to de - pop bc ; recover function & unit - rst 08 ; perform seek - ;call 0FFF0H - ret ; ; multiply 8-bit values @@ -557,6 +730,103 @@ mult8_noadd: djnz mult8_loop ret +rl32: + ; Left shift DE:HL by B bits (B > 0) + or a ; clear carry + rl l ; rotate L thru carry + rl h ; rotate H thru carry + rl e ; rotate E thru carry + rl d ; rotate D thru carry + djnz rl32 ; loop B times + ret ; done + +cin$echo: ; get console input, echo it, and shift to upper case + call ?const ; check for char + or a ; set flags + jr z,cin$echo1 ; nope, continue + call ?conin ; eat extraneous char + jr cin$echo ; and loop +cin$echo1: + call ?conin ; get char + push af ; save it + ld c,a ; put in C + call ?cono ; echo + pop af ; recover it + cp 'a' ; compare + ret c ; done if carry + sub 'a' - 'A' ; make upper case + ret ; and done + +; call ?const ! ora a ! jz u$c1 ; see if any char already struck +; call ?conin ! jmp u$conin$echo ; yes, eat it and try again +;u$c1: +; call ?conin ! push psw +; mov c,a ! call ?cono +; pop psw ! cpi 'a' ! rc +; sui 'a'-'A' ; make upper case +; ret + + +err_nodisk: + ld hl,str_err_nodisk + jr err_perm +err_noslice: + ld hl,str_err_noslice + jr err_perm +err_perm: + call prt_err + jr err_ret +err_diskio: + cp -10 ; HBIOS read only error + jr z,err_rdonly ; if so, handle special + ld a,(@ermde) ; get error mode + cp 0FFh ; FFh means suppress + jr z,err_ret ; if so, go to err return + ld hl,str_err_diskio + call prt_err + ld hl,str_err_retry + call ?pmsg + call cin$echo + cp 'Y' + jr nz,err_ret ; return error to caller + ld hl,(retry$adr) ; get retry address + jp (hl) ; and go there +err_rdonly: + ld hl,str_err_rdonly + call prt_err + ld a,2 ; signal readonly media + ret +prt_err: + ld a,(@ermde) ; get error mode + cp 0FFh ; FFh means suppress + ret z ; if so, go to err return + push hl + call ?pderr + pop hl + jp ?pmsg +err_ret: + ld a,0FFh ; signal error + ret ; and done + +str_err_retry db ", Retry (Y/N)?",0 +str_err_nodisk db ", No disk",0 +str_err_noslice db ", No slice",0 +str_err_diskio db ", Disk I/O",0 +str_err_rdonly db ", Read Only",0 +str_err_prefix db 13,10,"BIOS Error: ",0 + +retry$adr dw ?wboot ; error retry address +curdph dw 0 ; working dph value +medid db 0 ; working media id value +unit db 0 ; working disk unit num +slice db 0 ; working slice num +lba dw 0,0 ; working lba +sps dw 0 ; sectors per slice +mbrsec ds 512 ; MBR sector buffer +dma dw 0 ; current DMA address +bank db 0 ; HBIOS DMA bank +func db 0 ; HBIOS function + ;rw$common: ; seek to correct track (if necessary), ; ; initialize DMA controller, ; ; and issue 1797 command. diff --git a/Source/CPM3/genbnk.dat b/Source/CPM3/genbnk.dat index 4a542bd3..7ece8384 100644 --- a/Source/CPM3/genbnk.dat +++ b/Source/CPM3/genbnk.dat @@ -8,12 +8,12 @@ MEMTOP = FD BNKSWT = Y COMBAS = 80 LERROR = Y -NUMSEGS = 03 +NUMSEGS = 04 MEMSEG00 = 01,43,00 MEMSEG01 = 0E,72,02 MEMSEG02 = 01,7F,03 MEMSEG03 = 01,7F,04 -MEMSEG04 = 00,C0,05 +MEMSEG04 = 01,7F,05 MEMSEG05 = 00,C0,06 MEMSEG06 = 00,C0,07 MEMSEG07 = 00,C0,08 @@ -57,7 +57,7 @@ ALTBNKSM = Y ALTBNKSN = Y ALTBNKSO = Y ALTBNKSP = Y -NDIRRECA = 02 +NDIRRECA = 08 NDIRRECB = 00 NDIRRECC = 00 NDIRRECD = 00 @@ -73,7 +73,7 @@ NDIRRECM = 00 NDIRRECN = 00 NDIRRECO = 00 NDIRRECP = 00 -NDTARECA = 02 +NDTARECA = 10 NDTARECB = 00 NDTARECC = 00 NDTARECD = 00 diff --git a/Source/CPM3/loader.asm b/Source/CPM3/loader.asm index ef80711d..974cd884 100644 --- a/Source/CPM3/loader.asm +++ b/Source/CPM3/loader.asm @@ -27,9 +27,13 @@ ; #INCLUDE "../ver.inc" ; +; BELOW, SYS_END MUST BE SET TO THE SIZE OF CPMLDR.BIN + SYS_LOC. IF +; THE SIZE OF CPMLDR.BIN CHANGES, SYS_SIZ MUST BE UPDATED!!! +; +SYS_SIZ .EQU $0F00 ; SIZE OF CPMLDR.BIN SYS_ENT .EQU $0100 ; SYSTEM (OS) ENTRY POINT ADDRESS SYS_LOC .EQU $0100 ; STARTING ADDRESS TO LOAD SYSTEM IMAGE -SYS_END .EQU $1480 ; ENDING ADDRESS OF SYSTEM IMAGE +SYS_END .EQU SYS_SIZ + SYS_LOC ; ENDING ADDRESS OF SYSTEM IMAGE ; SEC_SIZE .EQU 512 ; DISK SECTOR SIZE BLK_SIZE .EQU 128 ; OS BLOCK/RECORD SIZE diff --git a/Source/CPM3/move.z80 b/Source/CPM3/move.z80 index 1b5dc067..73cc13bb 100644 --- a/Source/CPM3/move.z80 +++ b/Source/CPM3/move.z80 @@ -69,7 +69,8 @@ xbnkmov: ; 1: TPA BID_AUX 8Ch ; 2: BUFS BID_AUX-1 8Bh ; 3: BUFS BID_AUX-2 8Ah -; ... +; 4: BUFS BID_AUX-3 89h +; 5: BUFS BID_AUX-4 88h ; ; N.B., Below BID_AUX is considered RAM disk bank. Need to ; make sure RAM disk is kept small enough to stay below diff --git a/Source/CPM3/optzpm.lib b/Source/CPM3/optzpm.lib index eba22e9b..62c2499d 100644 --- a/Source/CPM3/optzpm.lib +++ b/Source/CPM3/optzpm.lib @@ -1,5 +1,4 @@ - ; global assembler options for BANKED BIOS - ; with Boot Drive swapped into Drive A + ; global assembler options for ZPM BIOS true equ -1 false equ not true diff --git a/Source/CPM3/util.z80 b/Source/CPM3/util.z80 index 28b39244..7967727d 100644 --- a/Source/CPM3/util.z80 +++ b/Source/CPM3/util.z80 @@ -1,9 +1,10 @@ title 'Utility module for RomWBW' - maclib options.lib - - public addhla, bcd2bin, bin2bcd - public phex16, phex8, cout, crlf, crlf2 + public addhla + public phex16, phex8 + public cin, cout + public crlf, crlf2 + public bcd2bin, bin2bcd cseg @@ -14,45 +15,6 @@ addhla: inc h ret -bcd2bin: - ; convert A from packed bcd to binary - 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 - -bin2bcd: - ; convert A from binary to packed bcd - push bc - ld b,10 - ld c,-1 -bin2bcd1: - inc c - sub b - jr nc,bin2bcd1 - 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 - - if 0 -; ; Print the hex word value in HL ; phex16: @@ -104,16 +66,29 @@ hexconv: daa ret ; +; input character to A +; +cin: + push bc + push de + push hl + ld bc,0080h + rst 08 + ld a,e + pop hl + pop de + pop bc + ret +; ; output character from A ; cout: - ; save all incoming registers push af push bc push de push hl ld e,a - ld bc,0100h + ld bc,0180h rst 08 pop hl pop de @@ -134,16 +109,44 @@ crlf: call cout pop af ret - - else - -phex16: -phex8: -cout: -crlf2: -crlf: - halt - - endif +; +; Convert A from packed BCD to binary +; +bcd2bin: + 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 +; +; Convert A from binary to packed BCD +; +bin2bcd: + push bc + ld b,10 + ld c,-1 +bin2bcd1: + inc c + sub b + jr nc,bin2bcd1 + 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 end diff --git a/Source/Doc/Applications.md b/Source/Doc/Applications.md index 4a145533..aa4c8de6 100644 --- a/Source/Doc/Applications.md +++ b/Source/Doc/Applications.md @@ -360,7 +360,7 @@ message. ## Etymology -The `SYSCOPY` command is an original product and the source code is +The `MODE` command is an original product and the source code is provided in the RomWBW distribution. `\clearpage`{=latex} @@ -521,15 +521,20 @@ This application is provided by Will Sowerbutts. *``* is the filename of the ROM image file -Options: (access method is auto-detected by default) +FLASH4 will auto-detect most parameters so additional options should not +normally be required. + +Options: -| `/PARTIAL`: Allow flashing a large ROM from a smaller image file +| `/V`: Enable verbose output (one line per sector) +| `/P` or `/PARTIAL`: Allow flashing a large ROM from a smaller image file | `/ROM`: Allow read-only use of unknown chip types | `/Z180DMA`: Force Z180 DMA engine | `/UNABIOS`: Force UNA BIOS bank switching | `/ROMWBW`: Force RomWBW (v2.6+) bank switching | `/ROMWBWOLD`: Force RomWBW (v2.5 and earlier) bank switching | `/P112`: Force P112 bank switching +| `/N8VEMSBC`: Force N8VEM SBC (v1, v2), Zeta (v1) SBC bank switching ## Usage @@ -949,6 +954,24 @@ accurately pace the sound file output. If no system timer is available, a delay loop is calculated instead. The delay loop will not be as accurate as the system timer. +There are two modes of operations. A direct hardware interface for the +AY-3-8910 or YM2149 chips, or a compatibility layer thru HBIOS supporting +the SN76489 chip. + +By default the application will attempt to interface directly to the sound +chip. The optional argument `--hbios` supplied after the filename, will +enable the application to use the HBIOS sound driver. + +The HBIOS mode also support other switch as desribed below. + +| Switch | Description | +| ----------- | ------------------------------------------------------ | +| `--hbios` | Utilise HBIOS' sound driver | +| `+t1` | Play tune an octave higher | +| `+t2` | Play tune two octaves higher | +| `-t1` | Play tune an octave lower | +| `-t2` | Play tune two octaves lower | + All RomWBW operating system boot disks include a selection of sound files in user area 3. @@ -960,4 +983,4 @@ software was adapted and embedded from pre-existing sources. The YM player code is from MYMPLAY 0.4 by Lieves!Tuore and the PT player code is (c)2004-2007 S.V.Bulba . -The source code is provided in the RomWBW distribution. \ No newline at end of file +The source code is provided in the RomWBW distribution. diff --git a/Source/Doc/Architecture.md b/Source/Doc/Architecture.md index 90d531ba..d70b32ab 100644 --- a/Source/Doc/Architecture.md +++ b/Source/Doc/Architecture.md @@ -410,6 +410,28 @@ require double-buffering if the caller’s buffer is in the lower 32K of CPU address space. For optimal performance, such buffers should be placed in the upper 32K of CPU address space. +Error Codes +----------- + +The following error codes are defined generically for all HBIOS functions. +Most function calls will return a result in register A. + +_Code_ | _Meaning_ +------ | --------- +0 | function succeeded +-1 | undefined error +-2 | function not implemented +-3 | invalid function +-4 | invalid unit numberr +-5 | out of memory +-6 | parameter out of range +-7 | media not present +-8 | hardware not present +-9 | I/O error +-10 | write request to read-only media +-11 | device timeout +-12 | invalid configuration + `\clearpage`{=latex} Character Input/Output (CIO) @@ -536,6 +558,8 @@ unit. Register pair DE contains the line characteristics upon return. | C: Serial Device Attributes | D: Serial Device Type | E: Serial Device Number +| H: Serial Device Unit Mode +| L: Serial Device Unit I/O Base Address Reports information about the character device unit specified. Register C indicates the device attributes: 0=RS-232 and 1=Terminal. Register D @@ -563,7 +587,7 @@ _Id_ | _Device Type / Driver_ Disk Input/Output (DIO) ----------------------- -Character input/output functions require that a character unit be specified +Disk input/output functions require that a disk unit be specified in the C register. This is the logical disk unit number assigned during the boot process that identifies all disk i/o devices uniquely. @@ -583,16 +607,18 @@ MID\_FD144 | 6 | 3.5" 1.44M Floppy MID\_FD360 | 7 | 5.25" 360K Floppy MID\_FD120 | 8 | 5.25" 1.2M Floppy MID\_FD111 | 9 | 8" 1.11M Floppy +MID\_HDNEW | 10 | Hard Disk with 1024 Directory entries ### Function 0x10 -- Disk Status (DIOSTATUS) | _Entry Parameters_ | B: 0x10 +| C: Disk Device Unit ID | _Exit Results_ | A: Status (0=OK, else error) -### Function 0x11 -- Disk Status (DIORESET) +### Function 0x11 -- Disk Reset (DIORESET) | _Entry Parameters_ | B: 0x11 @@ -643,6 +669,7 @@ determine if the device supports LBA addressing. | _Entry Parameters_ | B: 0x13 | C: Disk Device Unit ID +| D: Bank ID | E: Block Count | HL: Buffer Address @@ -654,18 +681,18 @@ Read Block Count sectors to buffer address starting at current target sector. Current sector must be established by prior seek function; however, multiple read/write/verify function calls can be made after a seek function. Current sector is incremented after each sector successfully -read. On error, current sector is sector is sector where error occurred. +read. On error, current sector is sector where error occurred. Blocks read indicates number of sectors successfully read. Caller must ensure: 1) buffer address is large enough to contain data for -all sectors requested, and 2) entire buffer area resides in upper 32K of -memory. +all sectors requested, and 2) does not cross a 32k memory bank boundary. ### Function 0x14 -- Disk Write (DIOWRITE) | _Entry Parameters_ | B: 0x14 | C: Disk Device Unit ID +| D: Bank ID | E: Block Count | HL: Buffer Address @@ -677,12 +704,10 @@ Write Block Count sectors to buffer address starting at current target sector. Current sector must be established by prior seek function; however, multiple read/write/verify function calls can be made after a seek function. Current sector is incremented after each sector successfully -written. On error, current sector is sector is sector where error occurred. +written. On error, current sector is sector where error occurred. Blocks written indicates number of sectors successfully written. -Caller must ensure: 1) buffer address is large enough to contain data for -all sectors being written, and 2) entire buffer area resides in upper 32K -of memory. +Caller must ensure the source buffer does not cross a 32k memory bank boundary. ### Function 0x15 -- Disk Verify (DIOVERIFY) @@ -723,6 +748,8 @@ of memory. | C: Attributes | D: Device Type | E: Device Number +| H: Disk Device Unit Mode +| L: Disk Device Unit I/O Base Address Reports information about the character device unit specified. Register D indicates the device type (driver) and register E indicates the physical @@ -739,9 +766,9 @@ Bit 7: 1=Floppy, 0=Hard Disk (or similar, e.g. CF, SD, RAM) | Bits 1-0: Reserved | If Hard Disk: -| Bit 6: Removable\ +| Bit 6: Removable | Bits: 5-3: Type (0=Hard, 1=CF, 2=SD, 3=USB, -| 4=ROM, 5=RAM, 6=RAMF, 7=Reserved) +| 4=ROM, 5=RAM, 6=RAMF, 7=FLASH) | Bits 2-0: Reserved Each disk device is handled by an appropriate driver (IDE, SD, @@ -792,7 +819,6 @@ function will return an error status. | _Entry Parameters_ | B: 0x1A | C: Disk Device Unit ID -| HL: Buffer Address | _Exit Results_ | A: Status (0=OK, else error) @@ -912,6 +938,53 @@ to by HL. HL must point to a location in the top 32K of CPU address space. Write the entire contents of the Non-Volatile RAM from the buffer pointed to by HL. HL must point to a location in the top 32K of CPU address space. +### Function 0x26 -- RTC Get Alarm (RTCGETALM) + +| _Entry Parameters_ +| B: 0x26 + +| _Exit Results_ +| A: Status (0=OK, else error) + +Documentation required... + +### Function 0x27 -- RTC Set Alarm (RTCSETALM) + +| _Entry Parameters_ +| B: 0x27 + +| _Exit Results_ +| A: Status (0=OK, else error) + +Documentation required... + +### Function 0x28 -- RTC DEVICE (RTCDEVICE) + +| _Entry Parameters_ +| B: 0x28 +| C: RTC Device Unit ID + +| _Exit Results_ +| A: Status (0=OK, else error) +| D: Device Type +| E: Device Number +| H: RTC Device Unit Mode +| L: RTC Device Unit I/O Base Address + +Reports information about the RTC device unit specified. Register D +indicates the device type (driver) and register E indicates the physical +device number assigned by the driver. + +Each RTC device is handled by an appropriate driver (DSRTC, BQRTC, +etc.) which is identified by a device type id from the table below. + +**Type ID** | **Disk Device Type** +----------- | -------------------- +0x00 | DS1302 +0x10 | BQ4845P +0x20 | SIMH +0x30 | System Periodic Timer + `\clearpage`{=latex} Video Display Adapter (VDA) @@ -1069,8 +1142,10 @@ Keyboard should be flushed. | _Exit Results_ | A: Status (0=OK, else error) -| D=Device Type -| E=Device Number +| D: Device Type +| E: Device Number +| H: VDA Device Unit Mode +| L: VDA Device Unit I/O Base Address Reports information about the video device unit specified. @@ -1292,6 +1367,244 @@ codes as described at the start of this section. `\clearpage`{=latex} +Sound (SND) +------------ + +### Function 0x50 -- Sound Reset (SNDRESET) + +| _Entry Parameters_ +| B: 0x50 +| C: Audio Device Unit ID + +| _Exit Results_ +| A: Status (0=OK, else error) + +Reset the sound chip. Turn off all sounds and set volume on all +channels to silence. + +### Function 0x51 -- Sound Volume (SNDVOL) + +| _Entry Parameters_ +| B: 0x51 +| C: Audio Device Unit ID +| L: Volume (00=Silence, FF=Maximum) + +| _Exit Results_ +| A: Status (0=OK, else error) + +This function sets the sound chip volume parameter. The volume will +be applied when the next SNDPLAY function is invoked. + +Note that not all sounds chips implement 256 volume levels. The +driver will scale the volume to the closest possible level the +chip provides. + +### Function 0x52 -- Sound Period (SNDPRD) + +| _Entry Parameters_ +| B: 0x52 +| C: Audio Device Unit ID +| HL: Period + +| _Returned Values_ +| A: Status (0=OK, else error) + +This function sets the sound chip period parameter. The period will +be applied when the next SNDPLAY function is invoked. + +The period value is a driver specific value. To play standardized +notes, use the SNDNOTE function. A higher value will generate a lower +note. The maximum value that can be used is driver specific. If value +supplied is beyond driver capabilities, register A will be set to $FF. + +### Function 0x53 -- Sound Note (SNDNOTE) + +| _Entry Parameters_ +| B: 0x53 +| C: Audio Device Unit ID +| HL: Value of note to play + +| _Returned Values_ +| A: Status (0=OK, else error) + +This function sets the sound chip period parameter with steps of quarter +of a semitone. The value of 0 (lowest) corresponds to Bb/A# in octave 0. + +Increase by steps of 4 to select the next corresponding note. + +Increase by steps of 48 to select the same note in next octave. + +If the driver is able to generate the requested note, a success (0) is +returned, otherwise a non-zero error state will be returned. + +The sound chip resolution and its oscillator limit the range and +accuracy of the notes played. The typically range of the AY-3-8910 +is six octaves, Bb2/A#2-A7, where each value is a unique tone. Values +above and below can still be played but each quarter tone step may not +result in a note change. + +The following table shows the mapping of the input value in HL +to the corresponding octave and note. + +| Note | Oct 0 | Oct 1 | Oct 2 | Oct 3 | Oct 4 | Oct 5 | Oct 6 | Oct 7 | +|:----- | -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| +| Bb/A# | 0 | 48 | 96 | 144 | 192 | 240 | 288 | 336 | +| B | 4 | 52 | 100 | 148 | 196 | 244 | 292 | 340 | +| C | 8 | 56 | 104 | 152 | 200 | 248 | 296 | 344 | +| C#/Db | 12 | 60 | 108 | 156 | 204 | 252 | 300 | 348 | +| D | 16 | 64 | 112 | 160 | 208 | 256 | 304 | 352 | +| Eb/D# | 20 | 68 | 116 | 164 | 212 | 260 | 308 | 356 | +| E | 24 | 72 | 120 | 168 | 216 | 264 | 312 | 360 | +| F | 28 | 76 | 124 | 172 | 220 | 268 | 316 | 364 | +| F#/Gb | 32 | 80 | 128 | 176 | 224 | 272 | 320 | 368 | +| G | 36 | 84 | 132 | 180 | 228 | 276 | 324 | 372 | +| Ab/G# | 40 | 88 | 136 | 184 | 232 | 280 | 328 | 376 | +| A | 44 | 92 | 140 | 188 | 236 | 284 | 332 | 380 | + +### Function 0x54 -- Sound Play SNDPLAY) + +| _Entry Parameters_ +| B: 0x54 +| C: Audio Device Unit ID +| D: Channel + +| _Returned Values_ +| A: Status (0=OK, else error) + +This function applies the previously specified volume and period by +programming the sound chip with the appropriate values. The values +are applied to the specified channel of the chip. + +For example, to play a specific note on Audio Device UNit 0, +the following HBIOS calls would need to be made: + +``` +HBIOS B=51 C=00 L=80 ; Set volume to half level +HBIOS B=53 C=00 L=69 ; Select Middle C (C4) assuming SN76489 +HBIOS B=54 C=00 D=01 ; Play note on Channel 1 +``` + +### Function 0x55 -- Sound Query (SNDQUERY) + +| _Entry Parameters_ +| B: 0x55 +| C: Audio Device Unit ID +| E: Subfunction + +| _Returned Values_ +| A: Status (0=OK, else error) + +This function will return the status of the current pending command or +key aspects of the specific Audio Device. + +#### SNDQUERY Subfunction 0x01 -- Get count of audio channels supported (SNDQ_CHCNT) + +| _Entry Parameters_ +| B: 0x55 +| E: 0x01 + +| _Returned Values_ +| A: Status (0=OK, else error) +| B: Count of standard tone channels +| C: Count of noise tone channels + +#### SNDQUERY Subfunction 0x02 -- Get current volume setting (SNDQ_VOL) + +| _Entry Parameters_ +| B: 0x55 +| E: 0x02 + +| _Returned Values_ +| A: Status (0=OK, else error) +| H: 0 +| L: Current volume setting + +#### SNDQUERY Subfunction 0x03 -- Get current period setting (SNDQ_PERIOD) + +| _Entry Parameters_ +| B: 0x55 +| E: 0x03 + +| _Returned Values_ +| A: Status (0=OK, else error) +| HL: Current period setting + +#### SNDQUERY Subfunction 0x04 -- Get device details (SNDQ_DEV) + +| _Entry Parameters_ +| B: 0x55 +| E: 0x04 + +| _Returned Values_ +| A: Status (0=OK, else error) +| B: Driver identity +| HL: Driver specific port settings +| DE: Driver specific port settings + +Reports information about the audio device unit specified. + +Register B reports the audio device type (see below). + +Registers HL and DE contain relevant port addresses for the hardware +specific to each device type. + +The currently defined audio device types are: + +AUDIO ID | Value | Device | Returned registers +-------------- | ----- | ---------- | -------------------------------------------- +SND_SN76489 | 0x01 | SN76489 | E: Left channel port, L: Right channel port +SND_AY38910 | 0x02 | AY-3-8910 | D: Address port, E: Data port +SND_BITMODE | 0x03 | I/O PORT | D: Address port, E: Bit mask + +### Function 0x56 -- Sound Duration (SNDDUR) + +| _Entry Parameters_ +| B: 0x56 +| C: Audio Device Unit ID +| HL: Duration + +| _Returned Values_ +| A: Status (0=OK, else error) + +This function sets the duration of the note to be played in milliseconds. + +If the duration is set to zero, then the play function will operate in a non-blocking +mode. i.e. a tone will start playing and the play function will return. The tone will +continue to play until the next tone is played. I/O PORT are not compatible and will +not play a note if the duration is zero. + +For other values, when a tone is played, it will play for the duration defined in HL +and then return. + +### Function 0x57 -- Sound Device (SNDDEVICE) + +| _Entry Parameters_ +| B: 0x57 +| C: Sound Device Unit Number + +| _Exit Results_ +| A: Status (0=OK, else error) +| D: Serial Device Type +| E: Serial Device Number +| H: Serial Device Unit Mode +| L: Serial Device Unit I/O Base Address + +Reports information about the sound device unit specified. Register D +indicates the device type (driver) and register E indicates the physical +device number assigned by the driver. + +Each character device is handled by an appropriate driver (AY38910, SN76489, +etc.). The driver can be identified by the Device Type. The assigned Device +Types are listed below. + +_Id_ | _Device Type / Driver_ +---- | ---------------------- +0x00 | SN76489 +0x10 | AY38910 +0x20 | BITMODE + +`\clearpage`{=latex} + System (SYS) ------------ @@ -1299,13 +1612,47 @@ System (SYS) | _Entry Parameters_ | B: 0xF0 +| C: Subfunction (see below) | _Exit Results_ | A: Status (0=OK, else error) +This function performs various forms of a system reset depending on +the value of the subfucntion. See subfunctions below. + +#### SYSRESET Subfunction 0x00 -- Internal HBIOS Reset (RESINT) + +| _Entry Parameters_ +| BC: 0xF000 + +| _Returned Values_ +| A: Status (0=OK, else error) + Perform a soft reset of HBIOS. Releases all HBIOS memory allocated by current OS. Does not reinitialize physical devices. +#### SYSRESET Subfunction 0x01 -- Warm Start System (RESWARM) + +| _Entry Parameters_ +| BC: 0xF001 + +| _Returned Values_ +| + +Warm start the system returning to the boot loader prompt. Does not +reinitialize physical devices. + +#### SYSRESET Subfunction 0x02 -- Cold Start System (RESCOLD) + +| _Entry Parameters_ +| BC: 0xF002 + +| _Returned Values_ +| + +Perform a system cold start (like a power on). All devices are +reinitialized. + ### Function 0xF1 -- System Version (SYSVER) | _Entry Parameters_ @@ -1462,6 +1809,32 @@ available along with the registers/information returned. | A: Status (0=OK, else error) | E: Count of Serial Device Units +#### SYSGET Subfunction 0x01 -- Get Serial Unit Function (CIOFN) + +| _Entry Parameters_ +| BC: 0xF801 +| D: CIO Function +| E: Unit + +| _Returned Values_ +| A: Status (0=OK, else error) +| HL: Driver Function Address +| DE: Unit Data Address + +This function will lookup the actual driver function address and +unit data address inside the HBIOS driver. On entry, place the +CIO function number to lookup in D and the CIO unit number in E. +On return, HL will contain the address of the requested function +in the HBIOS driver (in the HBIOS bank). DE will contain the +associated unit data address (also in the HBIOS bank). See +Appendix A for details. + +This function can be used to speed up HBIOS calls by looking up the +function and data address for a specific driver function. After this, +the caller can use interbank calls directly to the function in the +driver which bypasses the overhead of the normal function invocation +lookup. + #### SYSGET Subfunction 0x10 -- Get Disk Device Unit Count (DIOCNT) | _Entry Parameters_ @@ -1471,6 +1844,40 @@ available along with the registers/information returned. | A: Status (0=OK, else error) | E: Count of Disk Device Units +#### SYSGET Subfunction 0x11 -- Get Disk Unit Function (DIOFN) + +| _Entry Parameters_ +| BC: 0xF811 +| D: DIO Function +| E: Unit + +| _Returned Values_ +| A: Status (0=OK, else error) +| HL: Driver Function Address +| DE: Unit Data Address + +This function will lookup the actual driver function address and +unit data address inside the HBIOS driver. On entry, place the +DIO function number to lookup in D and the DIO unit number in E. +On return, HL will contain the address of the requested function +in the HBIOS driver (in the HBIOS bank). DE will contain the +associated unit data address (also in the HBIOS bank). + +This function can be used to speed up HBIOS calls by looking up the +function and data address for a specific driver function. After this, +the caller can use interbank calls directly to the function in the +driver which bypasses the overhead of the normal function invocation +lookup. + +#### SYSGET Subfunction 0x20 -- Get Disk Device Unit Count (RTCCNT) + +| _Entry Parameters_ +| BC: 0xF820 + +| _Returned Values_ +| A: Status (0=OK, else error) +| E: Count of RTC Device Units + #### SYSGET Subfunction 0x40 -- Get Video Device Unit Count (VDACNT) | _Entry Parameters_ @@ -1480,6 +1887,67 @@ available along with the registers/information returned. | A: Status (0=OK, else error) | E: Count of Video Device Units +#### SYSGET Subfunction 0x41 -- Get Video Unit Function (VDAFN) + +| _Entry Parameters_ +| BC: 0xF841 +| D: VDA Function +| E: Unit + +| _Returned Values_ +| A: Status (0=OK, else error) +| HL: Driver Function Address +| DE: Unit Data Address + +This function will lookup the actual driver function address and +unit data address inside the HBIOS driver. On entry, place the +VDA function number to lookup in D and the VDA unit number in E. +On return, HL will contain the address of the requested function +in the HBIOS driver (in the HBIOS bank). DE will contain the +associated unit data address (also in the HBIOS bank). See +Appendix A for details. + +This function can be used to speed up HBIOS calls by looking up the +function and data address for a specific driver function. After this, +the caller can use interbank calls directly to the function in the +driver which bypasses the overhead of the normal function invocation +lookup. + +#### SYSGET Subfunction 0x50 -- Get Sound Device Unit Count (SNDCNT) + +| _Entry Parameters_ +| BC: 0xF850 + +| _Returned Values_ +| A: Status (0=OK, else error) +| E: Count of Sound Device Units + +#### SYSGET Subfunction 0x51 -- Get Sound Unit Function (SNDFN) + +| _Entry Parameters_ +| BC: 0xF851 +| D: SND Function +| E: Unit + +| _Returned Values_ +| A: Status (0=OK, else error) +| HL: Driver Function Address +| DE: Unit Data Address + +This function will lookup the actual driver function address and +unit data address inside the HBIOS driver. On entry, place the +SND function number to lookup in D and the SND unit number in E. +On return, HL will contain the address of the requested function +in the HBIOS driver (in the HBIOS bank). DE will contain the +associated unit data address (also in the HBIOS bank). See +Appendix A for details. + +This function can be used to speed up HBIOS calls by looking up the +function and data address for a specific driver function. After this, +the caller can use interbank calls directly to the function in the +driver which bypasses the overhead of the normal function invocation +lookup. + #### SYSGET Subfunction 0xD0 -- Get Timer Tick Count (TIMER) | _Entry Parameters_ @@ -1488,6 +1956,7 @@ available along with the registers/information returned. | _Returned Values_ | A: Status (0=OK, else error) | DE:HL: Current Timer Tick Count Value +| C: Tick frequency (typically 50 or 60) #### SYSGET Subfunction 0xD1 -- Get Seconds Count (SECONDS) @@ -1573,7 +2042,6 @@ available along with the registers/information used as input. | _Returned Values_ | A: Status (0=OK, else error) - #### SYSSET Subfunction 0xE0 -- Set Boot Information (BOOTINFO) | _Entry Parameters_ @@ -1721,3 +2189,35 @@ On entry, register E must contain an index into the interrupt vector table and register HL must contain the address of the new interrupt vector to be inserted in the table at the index. On return, HL will contain the previous address in the table at the index. + + +`\clearpage`{=latex} + +### Appendix A Driver Instance Data fields + +The following section outlines the read only data referenced by the +`SYSGET`, subfunctions `xxxFN` for specific drivers. + + +#### TMS9918 Driver: + +| Name | Offset | Size (bytes)| Description | +|--------|--------|-------------|-------------| +| PPIA | 0 | 1 | PPI PORT A | +| PPIB | 1 | 1 | PPI PORT B | +| PPIC | 2 | 1 | PPI PORT C | +| PPIX | 3 | 1 | PPI CONTROL PORT | +| DATREG | 4 | 1 | IO PORT ADDRESS FOR MODE 0 | +| CMDREG | 5 | 1 | IO PORT ADDRESS FOR MODE 1 | +| The following are the register mirror values that HBIOS used for initialisation | +| REG. 0 | 6 | 1 | $00 - NO EXTERNAL VID +| REG. 1 | 7 | 1 | $50 or $70 - SET MODE 1 and interrupt if enabled | +| REG. 2 | 8 | 1 | $00 - PATTERN NAME TABLE := 0 +| REG. 3 | 9 | 1 | $00 - NO COLOR TABLE +| REG. 4 | 10 | 1 | $01 - SET PATTERN GENERATOR TABLE TO $800 +| REG. 5 | 11 | 1 | $00 - SPRITE ATTRIBUTE IRRELEVANT +| REG. 6 | 12 | 1 | $00 - NO SPRITE GENERATOR TABLE +| REG. 7 | 13 | 1 | $F0 - WHITE ON BLACK +| DCNTL* | 14 | 1 | Z180 DMA/WAIT CONTROL | + +* ONLY PRESENT FOR Z180 BUILDS diff --git a/Source/Doc/Catalog.md b/Source/Doc/Catalog.md new file mode 100644 index 00000000..23b645e0 --- /dev/null +++ b/Source/Doc/Catalog.md @@ -0,0 +1,830 @@ +!include(Common.inc) +!def(document)(Disk Catalog) +!def(author)(Mykl Orders) +--- +title: | + | !product + | Version !ver + | + | !document +author: !author (mailto:!authmail) +date: !date +institution: !orgname +documentclass: article +classoption: + - oneside +toc: true +papersize: letter +geometry: + - top=1.5in + - bottom=1.5in + - left=1.0in + - right=1.0in +# - showframe +linestretch: 1.25 +colorlinks: true +fontfamily: helvet +fontsize: 12pt +header-includes: + - | + ```{=latex} + \usepackage{fancyhdr} + \usepackage{xhfill} + \renewcommand*{\familydefault}{\sfdefault} + \setstretch{1.25} % for TOC + ``` +--- + +```{=latex} +\clearpage +\pagestyle{fancyplain} +\fancyhf{} +\pagenumbering{arabic} +\lhead{\fancyplain{}{\nouppercase{\footnotesize \bfseries \leftmark \hfill !product !document}}} +\lfoot{\small RetroBrew Computing Group ~~ {\xrfill[3pt]{1pt}[cyan]} ~~ \thepage} +``` + +`\clearpage`{=latex} + +# RomWBW Distribution File Catalog + +This document is a reference to the files found on the disk media +distributed with RomWBW. Specifically, RomWBW provides a set +of floppy and hard disk images in the Binary directory of the +distribution. The contents of these images is listed here. + +The files on the disk images were sourced from a variety of locations. +The primary sources of these files are listed below. Note that the +primary documentation for each of these sources is listed. You are +strongly encouraged to refer to this documentation for more information +on using the applications and files listed. + +## Sources + +- **RomWBW**: RomWBW Custom Applications + + Documentation: RomWBW Applications.pdf* + + These files are custom applications built exclusively to enhance the + functionality of RomWBW. In some cases they are built from scratch + while others are customized versions of well known CP/M tools. + +- **CPM22**: Digital Research CP/M-80 2.2 Distribution Files + + Documentation: CPM Manual.pdf + + These files are from the official Digital Research distribution + of CP/M 2.2. Applications have been patched according to the + DRI patch list. + +- **ZSDOS**: ZSDOS 1.1 Disk Operating System Distribution Files + + Documentation: *ZSDOS Manual.pdf* + + These files are from the official ZSDOS 1.1 distribution. Some of + the files are redistributions of applications from other sources. + +- **ZCPR**: ZCPR 1.0 Command Processor Distribution Files + + Documentation: *ZCPR Manual.pdf* + + These files are from the ZCPR 1.0 distribution. + +- **NZCOM**: NZCOM Automatic Z-System Distribution Files + + Documentation: *NZCOM Users Manual.pdf* + + These files are from the last official release of NZCOM. + +- **CPM3**: Digital Research CP/M 3 Distribution Files + + Documentation: *CPM3 Users Guide.pdf*, *CPM3 System Guide.pdf*, + *CPM3 Programmers Guide.pdf*, *CPM3 Command Summary.pdf* + + These files are from the official Digital Research distribution of + CP/M 3. Applications have been patched according to the DRI + patch list. + +- **ZPM3**: Digital Research CP/M-80 2.2 Distribution Files + + Documentation: *CPM Manual.pdf* + + These files are from Simeon Cran's ZPM3 operating system distribution. + +`\clearpage`{=latex} + +# CPM 2.2 Boot Disk + +| Floppy Disk Image: **fd_cpm22.img** +| Hard Disk Image: **hd_cpm22.img** +| Combo Disk Image: **Slice 0** + +| **User 0** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ASM.COM` | CPM22 | DRI 8080 Assembler | +| `CR.COM` | -- | Crunch archiver | +| `DDT.COM` | CPM22 | DRI Dynamic Debugger | +| `DDTZ.DOC` | -- | Z80 replacement for DDT | +| `DIRX.COM` | -- | Directory lister with file sizes | +| `DUMP.COM` | CPM22 | DRI type contents of disk file in hex | +| `ED.COM` | CPM22 | DRI context editor | +| `KERMIT.COM` | -- | Generic CP/M 2.2 Kermit communication application | +| `LBREXT.COM` | -- | Extract library files | +| `LIB.COM` | -- | DRI Library manager | +| `LINK.COM` | -- | DRI CPM relocatable linker | +| `LOAD.COM` | -- | DRI hex file loader into memory | +| `MAC.COM` | -- | DRI CPM macro assembler | +| `MBASIC.COM` | -- | Microsoft Basic | +| `PIP.COM` | CPM22 | DRI Periperal Interchange Program | +| `PMARC.COM` | -- | LHA file compressor | +| `PMEXT.COM` | -- | Extractor for PMARC archives | +| `RMAC.COM` | -- | DRI Relocatable Macro Assembler | +| `STAT.COM` | CPM22 | DRI statistices about file storage and device assignment | +| `SUBMIT.COM` | CPM22 | DRI batch processor | +| `UNCR.COM` | -- | NZCOM Uncrunch decompression | +| `UNZIP.COM` | -- | Extractor for ZIP archives | +| `XSUB.COM` | CPM22 | DRI eXtended submit | +| `ZSID.COM` | -- | DRI Z80 symbolic instruction debugger | +| `ASSIGN.COM` | RomWBW | RomWBW Drive/Slice mapper | +| `FAT.COM` | RomWBW | RomWBW FAT filesystem access | +| `FDU.COM` | RomWBW | RomWBW Floppy Disk Utility | +| `FORMAT.COM` | RomWBW | RomWBW media formatter (placeholder) | +| `INTTEST.COM` | RomWBW | RomWBW Interrupt test | +| `MODE.COM` | RomWBW | RomWBW Modify serial port characteristics | +| `RTC.COM` | RomWBW | RomWBW Display and set RTC | +| `SURVEY.COM` | RomWBW | System survey | +| `SYSCOPY.COM` | RomWBW | RomWBW Read/write system boot image | +| `SYSGEN.COM` | RomWBW | DRI CPM SYSGEN to put CPM onto a new drive | +| `TALK.COM` | RomWBW | RomWBW Direct console I/O to a serial port | +| `TIMER.COM` | RomWBW | RomWBW Display timer tick counter | +| `TUNE.COM` | RomWBW | RomWBW Play PT or MYM sound files | +| `XM.COM` | RomWBW | RomWBW XMODEM file transfer | +| `CPM.SYS` | RomWBW | CPM2.2 system image | +| `CLRDIR.COM` | -- | Max Scane's disk directory cleaner | +| `COMPARE.COM` | -- | FoxHollow compare two files | +| `DDTZ.COM` | -- | Z80 replacement for DDT | +| `FDISK80.COM` | -- | John Coffman's Partition editor for FAT filesystem | +| `FLASH.COM` | -- | Will Sowerbutts' in-situ EEPROM programmer | +| `NULU.COM` | -- | NZCOM new library utility | +| `UNARC.COM` | -- | Extractor for ARC archives | +| `ZAP.COM` | -- | Disk editor/patcher | +| `ZDE.COM` | -- | Z-system display editor | +| `ZDENST.COM` | -- | ZDE Installer | + +| **User 1** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `SAMPKEY.DOC` | -- | ZDE Distribution File | +| `SAMPKEY.ZDK` | -- | ZDE Distribution File | +| `SAMPKEY.ZDT` | -- | ZDE Distribution File | +| `ZDE10.DOC` | -- | ZDE Distribution File | +| `ZDE10.FOR` | -- | ZDE Distribution File | +| `ZDE10.NEW` | -- | ZDE Distribution File | +| `ZDE10.QRF` | -- | ZDE Distribution File | +| `ZDE10.TOC` | -- | ZDE Distribution File | +| `ZDE13.FOR` | -- | ZDE Distribution File | +| `ZDE13.NEW` | -- | ZDE Distribution File | +| `ZDE16.COM` | -- | ZDE Distribution File | +| `ZDE16.DIR` | -- | ZDE Distribution File | +| `ZDE16.FIX` | -- | ZDE Distribution File | +| `ZDE16.FOR` | -- | ZDE Distribution File | +| `ZDE16.NEW` | -- | ZDE Distribution File | +| `ZDE16A.COM` | -- | ZDE Distribution File | +| `ZDE16A.PAT` | -- | ZDE Distribution File | +| `ZDENST16.COM` | -- | ZDE Distribution File | +| `ZDEPROP.DOC` | -- | ZDE Distribution File | +| `ZDEPROP.Z80` | -- | ZDE Distribution File | +| `ZDKCOM13.COM` | -- | ZDE Distribution File | +| `ZDKCOM13.DOC` | -- | ZDE Distribution File | + +| **User 3** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ATTACK.PT3` | -- | Sound File | +| `BACKUP.PT3` | -- | Sound File | +| `BADMICE.PT3` | -- | Sound File | +| `DEMO.MYM` | -- | Sound File | +| `DEMO1.MYM` | -- | Sound File | +| `DEMO3.MYM` | -- | Sound File | +| `DEMO3MIX.MYM` | -- | Sound File | +| `DEMO4.MYM` | -- | Sound File | +| `HOWRU.PT3` | -- | Sound File | +| `ITERATN.PT3` | -- | Sound File | +| `LOOKBACK.PT3` | -- | Sound File | +| `LOUBOUTN.PT3` | -- | Sound File | +| `NAMIDA.PT3` | -- | Sound File | +| `RECOLL.PT3` | -- | Sound File | +| `SANXION.PT3` | -- | Sound File | +| `SYNCH.PT3` | -- | Sound File | +| `TOSTAR.PT3` | -- | Sound File | +| `VICTORY.PT3` | -- | Sound File | +| `WICKED.PT3` | -- | Sound File | +| `YEOLDE.PT3` | -- | Sound File | +| `YEOVIL.PT3` | -- | Sound File | + +`\clearpage`{=latex} + +# ZSDOS 1.1 Boot Disk + +| Floppy Disk Image: **fd_zsdos.img** +| Hard Disk Image: **hd_zsdos.img** +| Combo Disk Image: **Slice 1** + +| **User 0** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ASM.COM` | CPM22 | DRI 8080 Assembler | +| `CLOCKS.DAT` | ZSDOS | ZSDOS Library of clock drivers | +| `COPY.CFG` | ZSDOS | ZSDOS Configuration file for COPY.COM | +| `COPY.COM` | ZSDOS | ZSDOS File copier with file dates and archiving | +| `COPY.UPD` | ZSDOS | ZSDOS ??? | +| `CR.COM` | -- | Crunch archiver | +| `DATSWEEP.COM` | ZSDOS | ZSDOS Comprehensive file management utility | +| `DDT.COM` | CPM22 | DRI Dynamic Debugger | +| `DDTZ.DOC` | -- | Z80 replacement for DDT | +| `DIRX.COM` | -- | Directory lister with file sizes | +| `DSCONFIG.COM` | ZSDOS | ZSDOS DATSWEEP configuration tool | +| `DUMP.COM` | CPM22 | DRI type contents of disk file in hex | +| `ED.COM` | CPM22 | DRI context editor | +| `FA16.CFG` | ZSDOS | ZSDOS FILEATTR.COM v1.6 configuration file | +| `FA16.DOC` | ZSDOS | ZSDOS FILEATTR.COM v1.6 documentation | +| `FA16A.FOR` | ZSDOS | ZSDOS FILEATTR.COM v1.6a information | +| `FA16CFG.TXT` | ZSDOS | ZSDOS FILEATTR.COM v1.6 configuration instructions | +| `FILEATTR.COM` | ZSDOS | ZSDOS Modify file attributes | +| `FILEDATE.CFG` | ZSDOS | ZSDOS Configuration file for FILEDATE.COM | +| `FILEDATE.COM` | ZSDOS | ZSDOS Disk directory that allows sorting and selecting by date and name | +| `FILEDATE.COM` | ZSDOS | ZSDOS Disk directory that allows sorting and selecting by date and name | +| `INITDIR.CFG` | ZSDOS | ZSDOS Configuration file for INITDIR.COM | +| `INITDIR.COM` | ZSDOS | ZSDOS Prepare disks for P2DOS Stamps | +| `KERMIT.COM` | -- | Generic CP/M 2.2 Kermit communication application | +| `LBREXT.COM` | -- | Extract library files | +| `LDDS.COM` | ZSDOS | Clock driver | +| `LDNZT.COM` | ZSDOS | Clock driver | +| `LDP2D.COM` | ZSDOS | Clock driver | +| `LIB.COM` | -- | DRI Library manager | +| `LINK.COM` | -- | DRI CPM relocatable linker | +| `LOAD.COM` | -- | DRI hex file loader into memory | +| `MAC.COM` | -- | DRI CPM macro assembler | +| `MBASIC.COM` | -- | Microsoft Basic | +| `PIP.COM` | CPM22 | DRI Periperal Interchange Program | +| `PMARC.COM` | -- | LHA file compressor | +| `PMEXT.COM` | -- | Extractor for PMARC archives | +| `PUTBG.COM` | ZSDOS | ZSDOS Prepare disk for backgrounder | +| `PUTDS.COM` | ZSDOS | ZSDOS Prepare disk for datestamper | +| `RELOG.COM` | ZSDOS | ZSDOS relog disks after program that bypasses BDOS | +| `RMAC.COM` | -- | DRI Relocatable Macro Assembler | +| `SETTERM.COM` | ZSDOS | ZSDOS Installs terminal control codes into DateSamper utilities | +| `SETUPZST.COM` | ZSDOS | ZSDOS Select clock driver | +| `STAMPS.DAT` | ZSDOS | ZSDOS Library of stamping routines | +| `STAT.COM` | CPM22 | DRI statistices about file storage and device assignment | +| `SUBMIT.COM` | CPM22 | DRI batch processor | +| `SUPERSUB.COM` | ZSDOS | | +| `TD.CFG` | ZSDOS | ZSDOS Configuration file for TD.COM | +| `TD.COM` | ZSDOS | ZSDOS Time/Date utility | +| `TERMBASE.DAT` | ZSDOS | ZSDOS Terminal information library for SETTERM | +| `TESTCLOK.COM` | ZSDOS | ZSDOS Test various clock drivers | +| `UNCR.COM` | -- | NZCOM Uncrunch decompression | +| `UNZIP.COM` | -- | Extractor for ZIP archives | +| `XSUB.COM` | CPM22 | DRI eXtended submit | +| `ZCAL.COM` | ZSDOS | ZSDOS Show month calendar | +| `ZCNFG.COM` | ZSDOS | ZSDOS Configure various utilities | +| `ZCNFG24.CFG` | ZSDOS | ZSDOS Configuration file for ZCNFG.COM | +| `ZPATH.COM` | ZSDOS | ZSDOS Set BDOS and/or ZCPR command path | +| `ZSCONFIG.COM` | ZSDOS | ZSDOS Dynamically regulate many of ZSDOS features | +| `ZSID.COM` | -- | DRI Z80 symbolic instruction debugger | +| `ZSVSTAMP.COM` | ZSDOS | ZSDOS Save/restore file timestamp | +| `ZSVSTAMP.DOC` | ZSDOS | ZSDOS ZSVSTAMP.COM documentation | +| `ZXD.CFG` | ZSDOS | ZSDOS Configuration file for ZXD.COM | +| `ZXD.COM` | ZSDOS | ZSDOS Extended directory utility | +| `ASSIGN.COM` | RomWBW | RomWBW Drive/Slice mapper | +| `FAT.COM` | RomWBW | RomWBW FAT filesystem access | +| `FDU.COM` | RomWBW | RomWBW Floppy Disk Utility | +| `FORMAT.COM` | RomWBW | RomWBW media formatter (placeholder) | +| `INTTEST.COM` | RomWBW | RomWBW Interrupt test | +| `MODE.COM` | RomWBW | RomWBW Modify serial port characteristics | +| `RTC.COM` | RomWBW | RomWBW Display and set RTC | +| `SURVEY.COM` | RomWBW | System survey | +| `SYSCOPY.COM` | RomWBW | RomWBW Read/write system boot image | +| `SYSGEN.COM` | RomWBW | DRI CPM SYSGEN to put CPM onto a new drive | +| `TALK.COM` | RomWBW | RomWBW Direct console I/O to a serial port | +| `TIMER.COM` | RomWBW | RomWBW Display timer tick counter | +| `TUNE.COM` | RomWBW | RomWBW Play PT or MYM sound files | +| `XM.COM` | RomWBW | RomWBW XMODEM file transfer | +| `ZSYS.SYS` | RomWBW | ZSDOS system image | +| `CLRDIR.COM` | -- | Max Scane's disk directory cleaner | +| `COMPARE.COM` | -- | FoxHollow compare two files | +| `DDTZ.COM` | -- | Z80 replacement for DDT | +| `FDISK80.COM` | -- | John Coffman's Partition editor for FAT filesystem | +| `FLASH.COM` | -- | Will Sowerbutts' in-situ EEPROM programmer | +| `NULU.COM` | -- | NZCOM new library utility | +| `UNARC.COM` | -- | Extractor for ARC archives | +| `ZAP.COM` | -- | Disk editor/patcher | +| `ZDE.COM` | -- | Z-system display editor | +| `ZDENST.COM` | -- | ZDE Installer | + +| **User 1** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `SAMPKEY.DOC` | -- | ZDE Distribution File | +| `SAMPKEY.ZDK` | -- | ZDE Distribution File | +| `SAMPKEY.ZDT` | -- | ZDE Distribution File | +| `ZDE10.DOC` | -- | ZDE Distribution File | +| `ZDE10.FOR` | -- | ZDE Distribution File | +| `ZDE10.NEW` | -- | ZDE Distribution File | +| `ZDE10.QRF` | -- | ZDE Distribution File | +| `ZDE10.TOC` | -- | ZDE Distribution File | +| `ZDE13.FOR` | -- | ZDE Distribution File | +| `ZDE13.NEW` | -- | ZDE Distribution File | +| `ZDE16.COM` | -- | ZDE Distribution File | +| `ZDE16.DIR` | -- | ZDE Distribution File | +| `ZDE16.FIX` | -- | ZDE Distribution File | +| `ZDE16.FOR` | -- | ZDE Distribution File | +| `ZDE16.NEW` | -- | ZDE Distribution File | +| `ZDE16A.COM` | -- | ZDE Distribution File | +| `ZDE16A.PAT` | -- | ZDE Distribution File | +| `ZDENST16.COM` | -- | ZDE Distribution File | +| `ZDEPROP.DOC` | -- | ZDE Distribution File | +| `ZDEPROP.Z80` | -- | ZDE Distribution File | +| `ZDKCOM13.COM` | -- | ZDE Distribution File | +| `ZDKCOM13.DOC` | -- | ZDE Distribution File | + +| **User 3** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ATTACK.PT3` | -- | Sound File | +| `BACKUP.PT3` | -- | Sound File | +| `BADMICE.PT3` | -- | Sound File | +| `DEMO.MYM` | -- | Sound File | +| `DEMO1.MYM` | -- | Sound File | +| `DEMO3.MYM` | -- | Sound File | +| `DEMO3MIX.MYM` | -- | Sound File | +| `DEMO4.MYM` | -- | Sound File | +| `HOWRU.PT3` | -- | Sound File | +| `ITERATN.PT3` | -- | Sound File | +| `LOOKBACK.PT3` | -- | Sound File | +| `LOUBOUTN.PT3` | -- | Sound File | +| `NAMIDA.PT3` | -- | Sound File | +| `RECOLL.PT3` | -- | Sound File | +| `SANXION.PT3` | -- | Sound File | +| `SYNCH.PT3` | -- | Sound File | +| `TOSTAR.PT3` | -- | Sound File | +| `VICTORY.PT3` | -- | Sound File | +| `WICKED.PT3` | -- | Sound File | +| `YEOLDE.PT3` | -- | Sound File | +| `YEOVIL.PT3` | -- | Sound File | + +`\clearpage`{=latex} + +# NZCOM Boot Disk + +| Floppy Disk Image: **fd_nzcom.img** +| Hard Disk Image: **hd_nzcom.img** +| Combo Disk Image: **Slice 2** + +| **User 0** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `!(C)1988` | NZCOM | | +| `!NZ-COM` | NZCOM | | +| `!VERS--1.2H` | NZCOM | | +| `ALIAS.CMD` | NZCOM | NZCOM Aliases file for ARUNZ.COM | +| `ARUNZ.COM` | NZCOM | NZCOM Invoke an alias in ALIAS.CMD | +| `BGZRDS19.LBR` | NZCOM | | +| `CLEDINST.COM` | NZCOM | Command line editing and history shell installer | +| `CLEDSAVE.COM` | NZCOM | Write command line history to disk | +| `CONFIG.LBR` | NZCOM | | +| `COPY.COM` | NZCOM | ZSDOS File copier with file dates and archiving | +| `CPSET.COM` | NZCOM | NZCOM Create multiple definitions for CRT and PRT | +| `CRUNCH.COM` | NZCOM | NZCOM Text compression | +| `DOCFILES.LBR` | NZCOM | | +| `EDITNDR.COM` | NZCOM | NZCOM Associate names with directories | +| `FCP.LBR` | NZCOM | NZCOM ??? Flow control | +| `FF.COM` | NZCOM | NZCOM File finder | +| `HELP.COM` | NZCOM | DRI CPM+ | +| `HLPFILES.LBR` | NZCOM | | +| `IF.COM` | NZCOM | NZCOM Flow condition tester for FCP | +| `JETLDR.COM` | NZCOM | NZCOM General-purpose module loader | +| `KERMIT.COM` | -- | Generic CP/M 2.2 Kermit communication application | +| `LBREXT.COM` | NZCOM | Extract library files | +| `LBRHELP.COM` | NZCOM | | +| `LDIR.COM` | NZCOM | NZCOM Display the directory of a library | +| `LPUT.COM` | NZCOM | NZCOM Put files into a library | +| `LSH-HELP.COM` | NZCOM | | +| `LSH.COM` | NZCOM | | +| `LSH.WZ` | NZCOM | | +| `LSHINST.COM` | NZCOM | | +| `LX.COM` | NZCOM | NZCOM Extract and execute a memeber of a library | +| `MKZCM.COM` | NZCOM | NZCOM NZCOM system defining utility | +| `NAME.COM` | NZCOM | NZCOM Name a drive/user | +| `NZ-DBASE.INF` | NZCOM | NZCOM Dbase information | +| `NZBLITZ.COM` | NZCOM | | +| `NZBLTZ14.CFG` | NZCOM | | +| `NZBLTZ14.HZP` | NZCOM | | +| `NZCOM.COM` | NZCOM | NZCOM system loader from CP/M | +| `NZCOM.LBR` | NZCOM | NZCOM Library of NZCOM system modules | +| `NZCPR.LBR` | NZCOM | NZCOM Default command processor | +| `PATH.COM` | NZCOM | NZCOM Set/display command search path | +| `PUBLIC.COM` | NZCOM | | +| `PWD.COM` | NZCOM | | +| `RCP.LBR` | NZCOM | NZCOM Resident command package | +| `RELEASE.NOT` | NZCOM | | +| `SAINST.COM` | NZCOM | | +| `SALIAS.COM` | NZCOM | NZCOM Screen alias | +| `SAVENDR.COM` | NZCOM | NZCOM Save named directory assignments to a file | +| `SDZ.COM` | NZCOM | NZCOM Super directory | +| `SHOW.COM` | NZCOM | NZCOM Show resident commands | +| `SUB.COM` | NZCOM | | +| `SUBMIT.COM` | -- | DRI batch processor | +| `TCAP.LBR` | NZCOM | NZCOM Terminal capability descriptor library | +| `TCJ.INF` | NZCOM | | +| `TCJ25.WZ` | NZCOM | | +| `TCJ26.WZ` | NZCOM | | +| `TCJ27.WZ` | NZCOM | | +| `TCJ28.WZ` | NZCOM | | +| `TCJ29.WZ` | NZCOM | | +| `TCJ30.WZ` | NZCOM | | +| `TCJ31UPD.WZ` | NZCOM | | +| `TCJ32.WZ` | NZCOM | | +| `TCJ33UPD.WZ` | NZCOM | | +| `TCSELECT.COM` | NZCOM | NZCOM Create terminal capability file | +| `TY3ERA.COM` | NZCOM | NZCOM Type-3 transient program to erase a file | +| `TY3REN.COM` | NZCOM | NZCOM Type-3 transient program to rename a file | +| `TY4ERA.COM` | NZCOM | NZCOM Type-4 transient program to erase a file | +| `TY4REN.COM` | NZCOM | NZCOM Type-4 transient program to rename a file | +| `TY4SAVE.COM` | NZCOM | NZCOM Type-4 transient program to save memory to a file | +| `TY4SP.COM` | NZCOM | NZCOM Type-4 transient program ti display disk space | +| `UNCRUNCH.COM` | NZCOM | NZCOM Text decompressor | +| `VIEW.COM` | NZCOM | | +| `XTCAP.COM` | NZCOM | | +| `Z3LOC.COM` | NZCOM | NZCOM Display the addresses of the ZCPR3 CCP, BDOS, and BIOS | +| `Z3TCAP.TCP` | NZCOM | NZCOM Database of terminal descriptors | +| `ZCNFG.COM` | NZCOM | ZSDOS Configure various utilities | +| `ZERR.COM` | NZCOM | | +| `ZEX.COM` | NZCOM | NZCOM Memory-based batch processor | +| `ZF-DIM.COM` | NZCOM | NZCOM ZFILER shell for dim-video terminals | +| `ZF-REV.COM` | NZCOM | NZCOM ZFILER shell for reverse-video terminals | +| `ZFILEB38.LZT` | NZCOM | | +| `ZFILER.CMD` | NZCOM | NZCOM Macro script file for ZFILER | +| `ZHELPERS.LZT` | NZCOM | | +| `ZLT.COM` | NZCOM | | +| `ZNODES66.LZT` | NZCOM | | +| `ZSDOS.ZRL` | NZCOM | | +| `ZSYSTEM.IZF` | NZCOM | | +| `ASSIGN.COM` | RomWBW | RomWBW Drive/Slice mapper | +| `FAT.COM` | RomWBW | RomWBW FAT filesystem access | +| `FDU.COM` | RomWBW | RomWBW Floppy Disk Utility | +| `FORMAT.COM` | RomWBW | RomWBW media formatter (placeholder) | +| `INTTEST.COM` | RomWBW | RomWBW Interrupt test | +| `MODE.COM` | RomWBW | RomWBW Modify serial port characteristics | +| `RTC.COM` | RomWBW | RomWBW Display and set RTC | +| `SURVEY.COM` | RomWBW | System survey | +| `SYSCOPY.COM` | RomWBW | RomWBW Read/write system boot image | +| `SYSGEN.COM` | RomWBW | DRI CPM SYSGEN to put CPM onto a new drive | +| `TALK.COM` | RomWBW | RomWBW Direct console I/O to a serial port | +| `TIMER.COM` | RomWBW | RomWBW Display timer tick counter | +| `TUNE.COM` | RomWBW | RomWBW Play PT or MYM sound files | +| `XM.COM` | RomWBW | RomWBW XMODEM file transfer | +| `CPM.SYS` | RomWBW | | +| `ZSYS.SYS` | RomWBW | | +| `CLRDIR.COM` | -- | Max Scane's disk directory cleaner | +| `COMPARE.COM` | -- | FoxHollow compare two files | +| `DDTZ.COM` | -- | Z80 replacement for DDT | +| `FDISK80.COM` | -- | John Coffman's Partition editor for FAT filesystem | +| `FLASH.COM` | -- | Will Sowerbutts' in-situ EEPROM programmer | +| `NULU.COM` | -- | NZCOM new library utility | +| `UNARC.COM` | -- | Extractor for ARC archives | +| `ZAP.COM` | -- | Disk editor/patcher | +| `ZDE.COM` | -- | Z-system display editor | +| `ZDENST.COM` | -- | ZDE Installer | + +| **User 3** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ATTACK.PT3` | -- | Sound File | +| `BACKUP.PT3` | -- | Sound File | +| `BADMICE.PT3` | -- | Sound File | +| `DEMO.MYM` | -- | Sound File | +| `DEMO1.MYM` | -- | Sound File | +| `DEMO3.MYM` | -- | Sound File | +| `DEMO3MIX.MYM` | -- | Sound File | +| `DEMO4.MYM` | -- | Sound File | +| `HOWRU.PT3` | -- | Sound File | +| `ITERATN.PT3` | -- | Sound File | +| `LOOKBACK.PT3` | -- | Sound File | +| `LOUBOUTN.PT3` | -- | Sound File | +| `NAMIDA.PT3` | -- | Sound File | +| `RECOLL.PT3` | -- | Sound File | +| `SANXION.PT3` | -- | Sound File | +| `SYNCH.PT3` | -- | Sound File | +| `TOSTAR.PT3` | -- | Sound File | +| `VICTORY.PT3` | -- | Sound File | +| `WICKED.PT3` | -- | Sound File | +| `YEOLDE.PT3` | -- | Sound File | +| `YEOVIL.PT3` | -- | Sound File | + +`\clearpage`{=latex} + +# CP/M 3 Boot Disk + +| Floppy Disk Image: **fd_cpm3.img** +| Hard Disk Image: **hd_cpm3.img** +| Combo Disk Image: **Slice 3** + +| **User 0** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `DATE.COM` | CPM3 | DRI CPM+ Set or display the date and time | +| `DEVICE.COM` | CPM3 | DRI CPM+ Assign logical devices with one or more physical devices | +| `DIR.COM` | CPM3 | DRI CPM+ DIR with options | +| `DUMP.COM` | CPM3 | DRI type contents of disk file in hex | +| `ED.COM` | CPM3 | DRI context editor | +| `ERASE.COM` | CPM3 | DRI file deletion | +| `GENCOM.COM` | CPM3 | DRI CPM+ Generate special COM file with attached RSX files | +| `GET.COM` | CPM3 | DRI CPM+ Temporarily get console input form a disk file | +| `HELP.COM` | CPM3 | DRI CPM+ Display information on how to use commands | +| `HELP.HLP` | CPM3 | DRI CPM+ Databse of help information for HELP.COM | +| `HEXCOM.CPM` | CPM3 | DRI CPM+ Create a COM file from a nex file output by MAC | +| `INITDIR.COM` | CPM3 | DRI CPM+ Initializes a disk to allow time and date stamping | +| `KERMIT.COM` | -- | Generic CP/M 3 Kermit communication application | +| `PATCH.COM` | CPM3 | DRI CPM+ Display or install patch to the CPM+ system or command files | +| `PIP.COM` | CPM3 | DRI Periperal Interchange Program | +| `PUT.COM` | CPM3 | DIR CPM+ Temporarily redirect printer or console output to a disk file | +| `RENAME.COM` | CPM3 | DRI CPM+ Rename a file | +| `ROMWBW.TXT` | RomWBW | | +| `SAVE.COM` | CPM3 | DRI CPM+ Copy the contents of memory to a file | +| `SET.COM` | CPM3 | DIR CPM+ Set file options | +| `SETDEF.COM` | CPM3 | DIR CPM+ Set system options including the drive search chain | +| `SHOW.COM` | CPM3 | DIR CPM+ Display disk and drive statistics | +| `SUBMIT.COM` | CPM3 | DRI batch processor | +| `TYPE.COM` | CPM3 | DIR CPM+ Display the contents of an ASCII character file | +| `ZSID.COM` | CPM3 | DRI Z80 symbolic instruction debugger | +| `CPMLDR.COM` | RomWBW | DRI CPM 3.0 loader | +| `CPMLDR.SYS` | RomWBW | DRI CPM 3.0 loader | +| `CCP.COM` | CPM3 | DRI CPM+ Console Command Processor | +| `GENCPM.COM` | CPM3 | DRI CPM+ Create a memory image of CPM3.SYS | +| `GENRES.DAT` | RomWBW | | +| `GENBNK.DAT` | RomWBW | | +| `BIOS3.SPR` | RomWBW | DRI CPM+ GENCPM input file for non-banked BIOS | +| `BNKBIOS3.SPR` | RomWBW | DRI CPM+ GENCPM input file for banked BIOS | +| `BDOS3.SPR` | CPM3 | DRI CPM+ GENCPM input file for the non-banked BDOS | +| `BNKBDOS3.SPR` | CPM3 | DRI CPM+ GENCPM input file for banked BDOS | +| `RESBDOS3.SPR` | CPM3 | DRI CPM+ GENCPM input file for resident BDOS | +| `CPM3RES.SYS` | RomWBW | DRI CPM+ (non-banked) memory image | +| `CPM3BNK.SYS` | RomWBW | DRI CPM+ (banked) memory image | +| `GENCPM.DAT` | RomWBW | DRI CPM+ System generation tool data file | +| `CPM3.SYS` | RomWBW | DRI CPM+ (non-banked) memory image | +| `README.1ST` | CPM3 | | +| `CPM3FIX.PAT` | CPM3 | | +| `ASSIGN.COM` | RomWBW | RomWBW Drive/Slice mapper | +| `FAT.COM` | RomWBW | RomWBW FAT filesystem access | +| `FDU.COM` | RomWBW | RomWBW Floppy Disk Utility | +| `FORMAT.COM` | RomWBW | RomWBW media formatter (placeholder) | +| `INTTEST.COM` | RomWBW | RomWBW Interrupt test | +| `MODE.COM` | RomWBW | RomWBW Modify serial port characteristics | +| `RTC.COM` | RomWBW | RomWBW Display and set RTC | +| `SURVEY.COM` | RomWBW | System survey | +| `SYSCOPY.COM` | RomWBW | RomWBW Read/write system boot image | +| `SYSGEN.COM` | RomWBW | DRI CPM SYSGEN to put CPM onto a new drive | +| `TALK.COM` | RomWBW | RomWBW Direct console I/O to a serial port | +| `TIMER.COM` | RomWBW | RomWBW Display timer tick counter | +| `TUNE.COM` | RomWBW | RomWBW Play PT or MYM sound files | +| `XM.COM` | RomWBW | RomWBW XMODEM file transfer | +| `CLRDIR.COM` | -- | Max Scane's disk directory cleaner | +| `COMPARE.COM` | -- | FoxHollow compare two files | +| `DDTZ.COM` | -- | Z80 replacement for DDT | +| `FDISK80.COM` | -- | John Coffman's Partition editor for FAT filesystem | +| `FLASH.COM` | -- | Will Sowerbutts' in-situ EEPROM programmer | +| `NULU.COM` | -- | NZCOM new library utility | +| `UNARC.COM` | -- | Extractor for ARC archives | +| `ZAP.COM` | -- | Disk editor/patcher | +| `ZDE.COM` | -- | Z-system display editor | +| `ZDENST.COM` | -- | ZDE Installer | + +| **User 3** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ATTACK.PT3` | -- | Sound File | +| `BACKUP.PT3` | -- | Sound File | +| `BADMICE.PT3` | -- | Sound File | +| `DEMO.MYM` | -- | Sound File | +| `DEMO1.MYM` | -- | Sound File | +| `DEMO3.MYM` | -- | Sound File | +| `DEMO3MIX.MYM` | -- | Sound File | +| `DEMO4.MYM` | -- | Sound File | +| `HOWRU.PT3` | -- | Sound File | +| `ITERATN.PT3` | -- | Sound File | +| `LOOKBACK.PT3` | -- | Sound File | +| `LOUBOUTN.PT3` | -- | Sound File | +| `NAMIDA.PT3` | -- | Sound File | +| `RECOLL.PT3` | -- | Sound File | +| `SANXION.PT3` | -- | Sound File | +| `SYNCH.PT3` | -- | Sound File | +| `TOSTAR.PT3` | -- | Sound File | +| `VICTORY.PT3` | -- | Sound File | +| `WICKED.PT3` | -- | Sound File | +| `YEOLDE.PT3` | -- | Sound File | +| `YEOVIL.PT3` | -- | Sound File | + +`\clearpage`{=latex} + +# ZPM3 Boot Disk + +| Floppy Disk Image: **fd_zpm3.img** +| Hard Disk Image: **hd_zpm3.img** +| Combo Disk Image: **Slice 4** + +| **User 0** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `HELP.HLP` | ZPM3 | | +| `ROMWBW.TXT` | RomWBW | | +| `ZPMLDR.COM` | RomWBW | | +| `ZPMLDR.SYS` | RomWBW | | +| `CPMLDR.COM` | RomWBW | | +| `CPMLDR.SYS` | RomWBW | | +| `CPM3.SYS` | RomWBW | | +| `ZCCP.COM` | ZPM3 | | +| `ZINSTAL.ZPM` | ZPM3 | | +| `STARTZPM.COM` | ZPM3 | | +| `MAKEDOS.COM` | ZPM3 | | +| `GENCPM.DAT` | RomWBW | | +| `BNKBIOS3.SPR` | RomWBW | | +| `BNKBDOS3.SPR` | ZPM3 | | +| `RESBDOS3.SPR` | ZPM3 | | + +| **User 3** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ATTACK.PT3` | -- | Sound File | +| `BACKUP.PT3` | -- | Sound File | +| `BADMICE.PT3` | -- | Sound File | +| `DEMO.MYM` | -- | Sound File | +| `DEMO1.MYM` | -- | Sound File | +| `DEMO3.MYM` | -- | Sound File | +| `DEMO3MIX.MYM` | -- | Sound File | +| `DEMO4.MYM` | -- | Sound File | +| `HOWRU.PT3` | -- | Sound File | +| `ITERATN.PT3` | -- | Sound File | +| `LOOKBACK.PT3` | -- | Sound File | +| `LOUBOUTN.PT3` | -- | Sound File | +| `NAMIDA.PT3` | -- | Sound File | +| `RECOLL.PT3` | -- | Sound File | +| `SANXION.PT3` | -- | Sound File | +| `SYNCH.PT3` | -- | Sound File | +| `TOSTAR.PT3` | -- | Sound File | +| `VICTORY.PT3` | -- | Sound File | +| `WICKED.PT3` | -- | Sound File | +| `YEOLDE.PT3` | -- | Sound File | +| `YEOVIL.PT3` | -- | Sound File | + +| **User 10** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ALIAS.HLP` | -- | | +| `HP-RPN.HLP` | -- | | +| `HP-ZP.HLP` | -- | | +| `IF.HLP` | -- | | +| `MENU.HLP` | -- | | +| `VLU.HLP` | -- | | +| `ZFHIST.HLP` | -- | | +| `ZFILER.HLP` | -- | | +| `ZFMACRO.HLP` | -- | | +| `ZP.HLP` | -- | | + +| **User 14** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `COPY.CFG` | -- | | +| `ERASE.CFG` | -- | | +| `HELPC15.CFG` | -- | | +| `ZCNFG24.CFG` | -- | | +| `ZEX.CFG` | -- | | +| `ZF11.CFG` | -- | | +| `ZP17.CFG` | -- | | + +| **User 15** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ALIAS.COM` | -- | | +| `ARUNZ.COM` | -- | | +| `COPY.COM` | -- | | +| `DATE.COM` | CPM3 | | +| `DEV.COM` | -- | | +| `DEVICE.COM` | CPM3 | | +| `DIR.COM` | CPM3 | | +| `DISKINFO.COM` | -- | | +| `DU.COM` | -- | | +| `DUMP.COM` | CPM3 | | +| `ED.COM` | CPM3 | | +| `ERASE.COM` | CPM3 | | +| `GENCOM.COM` | CPM3 | | +| `GENCPM.COM` | CPM3 | | +| `GET.COM` | CPM3 | | +| `GOTO.COM` | -- | | +| `HELP.COM` | CPM3 | | +| `HEXCOM.COM` | CPM3 | | +| `IF.COM` | -- | | +| `INITDIR.COM` | CPM3 | | +| `KERMIT.COM` | CPM3 | | +| `LBREXT.COM` | -- | | +| `LIB.COM` | -- | | +| `LINK.COM` | -- | | +| `LOADSEG.COM` | -- | | +| `MAC.COM` | -- | | +| `MBASIC.COM` | -- | | +| `NAMES.NDR` | -- | | +| `PATCH.COM` | CPM3 | | +| `PIP.COM` | CPM3 | | +| `PUT.COM` | CPM3 | | +| `REMOVE.COM` | -- | | +| `RENAME.COM` | CPM3 | | +| `RMAC.COM` | -- | | +| `RSXDIR.COM` | -- | | +| `SAINST.COM` | -- | | +| `SALIAS.COM` | -- | | +| `SAVE.COM` | CPM3 | | +| `SET.COM` | CPM3 | | +| `SETDEF.COM` | CPM3 | | +| `SETPATH.COM` | -- | | +| `SHOW.COM` | CPM3 | | +| `SUBMIT.COM` | CPM3 | | +| `TCAP.Z3T` | -- | | +| `TYPE.COM` | CPM3 | | +| `VERROR.COM` | -- | | +| `VLU.COM` | -- | | +| `XREF.COM` | -- | | +| `ZCNFG.COM` | -- | | +| `ZERASE.COM` | -- | | +| `ZEX.COM` | -- | | +| `ZFILER.COM` | -- | | +| `ZHELP.COM` | -- | | +| `ZP.COM` | -- | | +| `ZSHOW.COM` | -- | | +| `ZSID.COM` | -- | | +| `ZXD.COM` | -- | | +| `AUTOTOG.COM` | ZPM3 | | +| `CLRHIST.COM` | ZPM3 | | +| `SETZ3.COM` | ZPM3 | | +| `ASSIGN.COM` | RomWBW | | +| `FAT.COM` | RomWBW | | +| `FDU.COM` | RomWBW | | +| `FORMAT.COM` | RomWBW | | +| `INTTEST.COM` | RomWBW | | +| `MODE.COM` | RomWBW | | +| `RTC.COM` | RomWBW | | +| `SURVEY.COM` | RomWBW | | +| `SYSCOPY.COM` | RomWBW | | +| `SYSGEN.COM` | RomWBW | | +| `TALK.COM` | RomWBW | | +| `TIMER.COM` | RomWBW | | +| `TUNE.COM` | RomWBW | | +| `XM.COM` | RomWBW | | +| `CLRDIR.COM` | -- | | +| `COMP.COM` | -- | | +| `DDTZ.COM` | -- | | +| `FDISK80.COM` | -- | | +| `FLASH.COM` | -- | | +| `NULU.COM` | -- | | +| `TCVIEW.COM` | -- | | +| `UNARC.COM` | -- | | +| `Z3LOC.COM` | -- | | +| `ZAP.COM` | -- | | +| `ZDE.COM` | -- | | +| `ZDENST.COM` | -- | | + +`\clearpage`{=latex} + +# WordStar 4 Application Disk + +| Floppy Disk Image: **fd_ws4.img** +| Hard Disk Image: **hd_ws4.img** +| Combo Disk Image: **Slice 5** + +| **User 0** | **Source** | **Description** | +| -------------- | ---------- | ------------------------------------------------------------ | +| `ANAGRAM.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `CHAPTER1.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `CHAPTER2.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `CHAPTER3.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `DIARY.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `DICTSORT.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `FIND.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `HOMONYMS.TXT` | WS4 | MicroPro WordStar 4 Distribution File | +| `HYEXCEPT.TXT` | WS4 | MicroPro WordStar 4 Distribution File | +| `HYPHEN.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `LOOKUP.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `MAINDICT.CMP` | WS4 | MicroPro WordStar 4 Distribution File | +| `MARKFIX.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `MOVEPRN.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `PATCH.LST` | WS4 | MicroPro WordStar 4 Distribution File | +| `PRINT.TST` | WS4 | MicroPro WordStar 4 Distribution File | +| `READ.ME` | WS4 | MicroPro WordStar 4 Distribution File | +| `README.` | WS4 | MicroPro WordStar 4 Distribution File | +| `REVIEW.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `RULER.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `SAMPLE1.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `SAMPLE2.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `SAMPLE3.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `SPELL.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `TABLE.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `TEXT.DOC` | WS4 | MicroPro WordStar 4 Distribution File | +| `TW.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `WC.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `WINSTALL.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `WORDFREQ.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `WS.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `WS.OVR` | WS4 | MicroPro WordStar 4 Distribution File | +| `WSCHANGE.COM` | WS4 | MicroPro WordStar 4 Distribution File | +| `WSCHANGE.OVR` | WS4 | MicroPro WordStar 4 Distribution File | +| `WSCHHELP.OVR` | WS4 | MicroPro WordStar 4 Distribution File | +| `WSHELP.OVR` | WS4 | MicroPro WordStar 4 Distribution File | +| `WSINDEX.XCL` | WS4 | MicroPro WordStar 4 Distribution File | +| `WSMSGS.OVR` | WS4 | MicroPro WordStar 4 Distribution File | +| `WSPRINT.OVR` | WS4 | MicroPro WordStar 4 Distribution File | +| `WSSHORT.OVR` | WS4 | MicroPro WordStar 4 Distribution File | \ No newline at end of file diff --git a/Source/Doc/GettingStarted.md b/Source/Doc/GettingStarted.md index 335703d6..78adf0cb 100644 --- a/Source/Doc/GettingStarted.md +++ b/Source/Doc/GettingStarted.md @@ -67,7 +67,7 @@ General features include: * Disk drivers for RAM, ROM, Floppy, IDE, CF, and SD * Serial drivers including UART (16550-like), ASCI, ACIA, SIO * Video drivers including TMS9918, SY6545, MOS8563, HD6445 -* Real time clock drivers including DS1322, BQ4845 +* Real time clock drivers including DS1302, BQ4845 * Multiple OS support including CP/M 2.2, ZSDOS, CP/M 3, ZPM3 * Built-in VT-100 terminal emulation support @@ -347,7 +347,7 @@ the first 256 8MB chunks of space on a single media. Of course, the problem is that CP/M-like operating systems have only 16 drive letters (A:-P:) available. Under the covers, RomWBW allows you to use any drive letter to refer to any slice of any media. The -`ASSIGN` command is allows you to view or change the drive letter +`ASSIGN` command allows you to view or change the drive letter mappings at any time. At startup, the operating system will automatically allocate a reasonable number of drive letters to the available storage devices. The allocation will depend on the number of @@ -756,13 +756,18 @@ likely to encounter problems. ### Notes +- You can change media, but it must be done while at the OS +command prompt and you **must** warm start CP/M by pressing +ctrl-c. This is a CP/M 2.2 constraint and is well documented +in the DRI manuals. + - The original versions of DDT, DDTZ, and ZSID used the RST 38 vector which conflicts with interrupt mode 1 use of this vector. The DDT, DDTZ, and ZSID applications in RomWBW have been modified -to use RTS 30 to avoid this issue. +to use RST 30 to avoid this issue. - Z-System applications will not run under CP/M 2.2. For example, -the `LDDS` date stamper with not run. +the `LDDS` date stamper will not run. ## ZSDOS 1.1 @@ -784,6 +789,10 @@ Manual.pdf"). may not work as expected. The best example is PIP which is not aware of the ZSDOS paths and will fail in some scenarios (use `COPY` instead). +- Although ZSDOS can recognize a media change in some cases, it will not +always work. You should only change media at a command prompt and be +sure to warm start the OS with a ctrl-c. + ## NZCOM Automatic Z-System NZCOM is a much further refined version of Z-System (ZCPR 3.4). NZCOM @@ -824,6 +833,14 @@ system tracks. `CPMLDR.SYS` chain loads `CPM3.SYS`. used to read the current date/time for file stamping, etc. You can use the `RTC` app to set the RTC clock. +- The `COPYSYS` command described in the DRI CP/M 3 documentation is +not provided with RomWBW. The RomWBW `SYSCOPY` command is used instead. + +- Although CP/M 3 is generally able to run CP/M 2.2 programs, this is +not universally true. This is especially true of the utility programs +included with the operating system. For example, the `SUBMIT` program +of CP/M 3 is completely different from the `SUBMIT` program of CP/M 2.2. + ## Simeon Cran's ZPM3 ZPM3 is an interesting combination of the features of both CP/M 3 and @@ -838,7 +855,9 @@ tracks of the disk. - `ZPMLDR` is included with ZPM3, but it is not working correctly. - The ZPM operating system is contained in the file called CPM3.SYS -which is confusing, but it is the author's intended way of using ZPM3. +which is confusing, but this is as intended by the ZPM3 distribution. +I believe it was done this way to make it easier for users to transition +from CP/M 3 to ZPM3. ## FreeRTOS @@ -1072,7 +1091,7 @@ update your ROM. The following is a typical example of transferring ROM image using XModem and flashing the chip in-situ. ``` -E>xm r rom.img +E>xm r rom.rom XMODEM v12.5 - 07/13/86 RBC, 28-Aug-2019 [WBW], ASCI @@ -1084,7 +1103,7 @@ To cancel: Ctrl-X, pause, Ctrl-X Thanks for the upload -E>flash write rom.img +E>flash write rom.rom FLASH4 by Will Sowerbutts version 1.2.3 Using RomWBW (v2.6+) bank switching. @@ -1115,12 +1134,81 @@ your choice. This process is described below in the Disk Images section. If you wish to update existing disk media in your system, you need to perform the following steps. -If the disk is bootable, you need to update the system tracks of the -disk. This is done using a SYSCOPY command such as `SYSCOPY -C:=B:ZSYS.SYS`. For a ZSDOS boot disk, use ZSYS.SYS. For a CP/M 2.2 -disk, use CPM.SYS. For a CP/M 3 or ZPM3 disk, use CPMLDR.SYS. -CPMLDR.SYS is not provided on the ROM disk, so you will need to -upload it from the distribution. +If the disk is bootable, you need to update the system image on the +disk using the procedure described below corresponsing to the +operating system on your disk. + +* **CP/M 2.2** + + Boot to CP/M 2.2 from ROM, then use `SYSCOPY` to update the system + image on **all** CP/M 2.2 boot disks/slices. The CP/M 2.2 system image + is called CPM.SYS and is found on the ROM disk. For example: + + `B>SYSCOPY C:=CPM.SYS` + +* **ZSDOS** + + Boot to Z-System from ROM, then use `SYSCOPY` to update the system + image on **all** ZSDOS boot disks/slices. The ZSDOS system image + is called ZSYS.SYS and is found on the ROM disk. For example: + + `B>SYSCOPY C:=ZSYS.SYS` + +* **NZCOM** + + NZCOM runs on top of either CP/M 2.2 or ZSDOS. By default, the + RomWBW disk image for NZCOM uses ZSDOS. Follow the corresponding + procedure above to update the system image on the NZCOM boot + disks/slices. + +* **CP/M 3** + + CP/M 3 uses a multi-step boot process involving multiple files. + The CP/M 3 boot files are not included on the ROM disk due to + space constraints. You will need to transfer the files to your + system from the RomWBW distribution directory Binary\\CPM3. + + After this is done, you will need to use `SYSCOPY` to place + the CP/M 3 loader image on the boot tracks of all CP/M 3 + boot disks/slices. The loader image is called `CPMLDR.SYS`. + You must then copy (at a minimum) `CPM3.SYS` and `CCP.COM` + onto the disk/slice. Assuming you copied the CP/M 3 boot files + onto your RAM disk at A:, you would use: + + ``` + A>B:SYSCOPY C:=CPMLDR.SYS + A>B:COPY CPM3.SYS C: + A>B:COPY CCP.COM C: + ``` + +* **ZPM3** + + ZPM3 uses a multi-step boot process involving multiple files. + The ZPM3 boot files are not included on the ROM disk due to + space constraints. You will need to transfer the files to your + system from the RomWBW distribution directory Binary\\ZPM3. + + After this is done, you will need to use `SYSCOPY` to place + the ZPM3 loader image on the boot tracks of all ZPM3 + boot disks/slices. The loader image is called `CPMLDR.SYS`. + You must then copy (at a minimum) `CPM3.SYS`, `ZCCP.COM`, + `ZINSTAL.ZPM`, and `STARTZPM.COM` onto the disk/slice. + Assuming you copied the ZPM3 boot files onto your RAM disk + at A:, you would use: + + ``` + A>B:SYSCOPY C:=CPMLDR.SYS + A>B:COPY CPM3.SYS C: + A>B:COPY ZCCP.COM C: + A>B:COPY ZINSTAL.ZPM C: + A>B:COPY STARTZPM.COM C: + ``` + + You may be wondering if the references to `CPMLDR.SYS` and + `CPM3.SYS` are typos. They are not. ZPM3 uses the same loader + image as CPM3. The ZPM3 main system code file is called `CPM3.SYS` + which is the same name as CP/M 3 uses, but the file contents are + not the same. Finally, if you have copies of any of the RomWBW custom applications on your hard disk, you need to update them with the latest copies. The @@ -1151,6 +1239,30 @@ images. * FAT.COM * TUNE.COM +# System Update + +If the system running ROMWBW utilizes the SST39SF040 Flash chip then it is possible to do a System Update in place of +a System Upgrade in some cases. + +A System Update would involve only updating the BIOS, ROM applications and CP/M system. + +A System Update may be more favorable than a System Upgrade in cases such as: + + - Overwriting of the ROM drive is not desired. + - Space is unavailable to hold a full ROMWBW ROM. + - To mimimize time taken to transfer and flash a full ROM. + - Configuration changes are only minor and do not impact disk applications. + +The ROMWBW build process generates a system upgrade file along with the normal ROM image and can be identified by the +extension ".upd". It will be 128Kb in size. In comparison the normal ROM image will have the extension ".rom" and be +512Kb or 1024Kb in size. + +Transferring and flashing the System Update is accomplished in the same manner as described above in *Upgrading* with +the required difference being that the flash application needs to be directed to complete a partial flash using the +/p command line switch. + +`E>flash write rom.upd /p` + # RomWBW Distribution All source code and distributions are maintained on GitHub. Code @@ -1191,12 +1303,17 @@ these applications are no longer provided. driver. * Ed Brindley contributed some of the code that supports the RC2014 platform. -* Phil Summers contributed Forth and BASIC in ROM as well as a long -list of general code enhancements. +* Phil Summers contributed Forth and BASIC in ROM, the AY-3-8910 sound +driver as well as a long list of general code enhancements. * Phillip Stevens contributed support for FreeRTOS. * Curt Mayer contributed the Linux / MacOS build process. -* UNA BIOS and FDISK80 is a product of John Coffman. +* UNA BIOS and FDISK80 are the products of John Coffman. * FLASH4 is a product of Will Sowerbutts. +* CLRDIR is a product of Max Scane. +* Tasty Basic is a product of Dimitri Theulings. +* Dean Netherton contributed the sound driver interface and +the SN76489 sound driver. +* The RomWBW Disk Catalog document was produced by Mykl Orders. Contributions of all kinds to RomWBW are very welcome. @@ -1209,6 +1326,7 @@ RetroBrew Computers projects is via the community forums: * [RC2014 Google Group](https://groups.google.com/forum/#!forum/rc2014-z80) * [retro-comp Google Group](https://groups.google.com/forum/#!forum/retro-comp) -Submission of issues and bugs are welcome at the [RomWBW GitHub Repository](https://github.com/wwarthen/RomWBW). +Submission of issues and bugs are welcome at the +[RomWBW GitHub Repository](https://github.com/wwarthen/RomWBW). Also feel free to email !author at [!authmail](mailto:!authmail). diff --git a/Source/Doc/Graphics/Hard Disk Anatomy.vsd b/Source/Doc/Graphics/Hard Disk Anatomy.vsd index 680e16e3..9e78f36f 100644 Binary files a/Source/Doc/Graphics/Hard Disk Anatomy.vsd and b/Source/Doc/Graphics/Hard Disk Anatomy.vsd differ diff --git a/Source/Doc/SIO+CTC Baud Rate Options.xlsx b/Source/Doc/SIO+CTC Baud Rate Options.xlsx new file mode 100644 index 00000000..632283c5 Binary files /dev/null and b/Source/Doc/SIO+CTC Baud Rate Options.xlsx differ diff --git a/Source/Forth/Build.cmd b/Source/Forth/Build.cmd index 08fb735b..fa958516 100644 --- a/Source/Forth/Build.cmd +++ b/Source/Forth/Build.cmd @@ -11,7 +11,7 @@ set ZXBINDIR=%TOOLS%/cpm/bin/ set ZXLIBDIR=%TOOLS%/cpm/lib/ set ZXINCDIR=%TOOLS%/cpm/include/ -zx zsm =camel80.azm -zx link -CAMEL80.BIN=CAMEL80 +zx zsm =camel80.azm -/l +zx link -CAMEL80.BIN[L200]=CAMEL80 diff --git a/Source/Forth/camel80.azm b/Source/Forth/camel80.azm index c74af4fc..c082ead8 100644 --- a/Source/Forth/camel80.azm +++ b/Source/Forth/camel80.azm @@ -1,15 +1,17 @@ -CIODEV_CONSOLE EQU 0D0h -CIOIN EQU 00h ; CHARACTER INPUT -CIOOUT EQU 01h ; CHARACTER OUTPUT -CIOIST EQU 02h ; CHARACTER INPUT STATUS -BID_BOOT EQU 00h -HB_BNKCALL EQU 0fff9h +CIODEV_CONSOLE EQU 0D0h +CIOIN EQU 00h ; CHARACTER INPUT +CIOOUT EQU 01h ; CHARACTER OUTPUT +CIOIST EQU 02h ; CHARACTER INPUT STATUS +BF_SYSRESET EQU 0F0h ; RESTART SYSTEM +BF_SYSRES_WARM EQU 01h ; WARM START (RESTART BOOT LOADER) + ; THE FOLLOWING NEED TO BE SYNCED WITH STD.ASM SO ROMLDR ; KNOWS WHERE THIS EXECUTES AT FTH_SIZ EQU 1700h FTH_LOC EQU 0200h +HB_LOC EQU 0FD80h ; Listing 2. ; =============================================== @@ -66,6 +68,14 @@ FTH_LOC EQU 0200h ; keywords are being passed in a ; macro. ; b1ackmai1er difficultylevelhigh@gmail.com +; 03-Dec 20 v1.02 Add James Bowmans double +; precision words as per RC2014 +; version. Increase terminal +; input buffer (TIB) size. +; b1ackmai1er difficultylevelhigh@gmail.com +; 22-Jan 21 v1.02 Adjust for revised HBIOS +; proxy size. +; b1ackmai1er difficultylevelhigh@gmail.com ; =============================================== ; Macros to define Forth headers ; HEAD label,length,name,action @@ -131,9 +141,10 @@ nexthl MACRO ; RELOCATED ENTRY POINT + CSEG .PHASE FTH_LOC -reset: ld hl,0FDFFh ; HBIOS address, rounded down +reset: ld hl,HB_LOC ; HBIOS address, rounded down ld l,0 ; = end of avail.mem (EM) dec h ; EM-100h ld sp,hl ; = top of param stack @@ -148,15 +159,17 @@ reset: ld hl,0FDFFh ; HBIOS address, rounded down jp COLD ; enter top-level Forth word ; Memory map: -; Terminal Input Buffer, 128 bytes + ; FTH_LOC Forth kernel = starts after ROMLDR ; ? h Forth dictionary (user RAM) +; EM-400h Terminal Input Buffer, 512 bytes +; Below user area ; EM-200h User area, 128 bytes ; EM-180h Parameter stack, 128B, grows down ; EM-100h HOLD area, 40 bytes, grows down ; EM-0D8h PAD buffer, 88 bytes ; EM-80h Return stack, 128 B, grows down -; EM End of RAM = start of HBIOS +; EM=HB_LOC End of RAM = start of HBIOS ; See also the definitions of U0, S0, and R0 ; in the "system variables & constants" area. ; A task w/o terminal input requires 200h bytes. @@ -332,10 +345,9 @@ KEY2: DW SAVEKEY,CFETCH,LIT,0,SAVEKEY,CSTORE ;X BYE i*x -- return to CP/M head bye,3,bye,docode - LD A,BID_BOOT ; BOOT BANK - LD HL,0 ; ADDRESS ZERO - CALL HB_BNKCALL ; DOES NOT RETURN - HALT + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_WARM ; WARM START + JP 0FFF0h ; CALL HBIOS ; STACK OPERATIONS ============================== diff --git a/Source/Forth/camel80h.azm b/Source/Forth/camel80h.azm index b3b6f079..15f195ef 100644 --- a/Source/Forth/camel80h.azm +++ b/Source/Forth/camel80h.azm @@ -39,7 +39,7 @@ ;Z tibsize -- n size of TIB head TIBSIZE,7,TIBSIZE,docon - dw 124 ; 2 chars safety zone + dw 512-2 ; 2 chars safety zone ;X tib -- a-addr Terminal Input Buffer ; HEX 82 CONSTANT TIB CP/M systems: 126 bytes @@ -47,7 +47,7 @@ ; head TIB,3,TIB,docon ; dw 82h head TIB,3,TIB,douser - dw -80h + dw -512 ;Z u0 -- a-addr current user area adrs ; 0 USER U0 @@ -1011,6 +1011,75 @@ WDS1: DW DUP,COUNT,TYPE,SPACE,NFATOLFA,FETCH DOTS1: DW II,FETCH,UDOT,LIT,-2,XPLUSLOOP,DOTS1 DOTS2: DW EXIT +;C D. d -- display d signed + head DDOT,2,D.,docolon + DW LESSNUM,DUP,TOR,DABS,NUMS + DW RFROM,SIGN,NUMGREATER,TYPE,SPACE,EXIT + +;X D+ d1 d2 -- d1+d2 Add double numbers + head DPLUS,2,D+,docode + exx + pop bc ; BC'=d2lo + exx + pop hl ; HL=d1hi,BC=d2hi + exx + pop hl ; HL'=d1lo + add hl,bc + push hl ; 2OS=d1lo+d2lo + exx + adc hl,bc ; HL=d1hi+d2hi+cy + ld b,h + ld c,l + next + +;C 2>R d -- 2 to R + head TWOTOR,3,2!>R,docolon + DW SWOP,RFROM,SWOP,TOR,SWOP,TOR,TOR,EXIT + +;C 2R> d -- fetch 2 from R + head TWORFROM,3,2R!>,docolon + DW RFROM,RFROM,RFROM,SWOP,ROT,TOR,EXIT + +TNEGATE: + call docolon + DW TOR,TWODUP,OR,DUP,qbranch,TNEG1,DROP,DNEGATE,lit,1 +TNEG1: + DW RFROM,PLUS,NEGATE,EXIT + +qtneg: + call docolon + DW ZEROLESS,qbranch,qtneg1,TNEGATE +qtneg1: + DW EXIT + +TSTAR: + call docolon + DW TWODUP,XOR,TOR + DW TOR,DABS,RFROM,ABS + DW TWOTOR + DW RFETCH,UMSTAR,lit,0 + DW TWORFROM,UMSTAR + DW DPLUS + DW RFROM + DW qtneg + DW EXIT + +TDIV: + call docolon + DW OVER,TOR,TOR + DW DUP,qtneg + DW RFETCH,UMSLASHMOD + DW ROT,ROT + DW RFROM,UMSLASHMOD + DW NIP,SWOP + DW RFROM,ZEROLESS,qbranch,tdiv1,DNEGATE +tdiv1: + DW EXIT + +;C M*/ d1 n2 u3 -- d=(d1*n2)/u3 double precision mult. div + head MSTARSLASH,3,M*/,docolon + DW TOR,TSTAR,RFROM,TDIV,EXIT + ;Z COLD -- cold start Forth system ; UINIT U0 #INIT CMOVE init user area ; 80 COUNT INTERPRET interpret CP/M cmd diff --git a/Source/HBIOS/API.txt b/Source/HBIOS/API.txt index 7b97b0cd..013ec895 100644 --- a/Source/HBIOS/API.txt +++ b/Source/HBIOS/API.txt @@ -45,14 +45,42 @@ GET ($F8): BC=Function/Subfunction A=Result E=Serial Unit Count + CIOFN ($01): + BC=Function/Subfunction A=Result + HL=Function Address + DE=Unit Data Address + DIOCNT ($10): BC=Function/Subfunction A=Result E=Disk Unit Count + DIOFN ($11): + BC=Function/Subfunction A=Result + HL=Function Address + DE=Unit Data Address + + RTCCNT ($20): + BC=Function/Subfunction A=Result + E=RTC Unit Count + VDACNT ($40): BC=Function/Subfunction A=Result E=Video Unit Count + VDAFN ($41): + BC=Function/Subfunction A=Result + HL=Function Address + DE=Unit Data Address + + SNDCNT ($50): + BC=Function/Subfunction A=Result + E=Sound Unit Count + + SNDFN ($51): + BC=Function/Subfunction A=Result + HL=Function Address + DE=Unit Data Address + TIMER ($D0): BC=Function/Subfunction A=Result DE:HL=Timer Value (32 bit) @@ -239,6 +267,8 @@ DEVICE ($06): D=Device Type E=Device Number C=Device Attributes + H=Device Mode + L=Base I/O Adr Serial Device Attributes Byte: 7: 0=RS-232, 1=Terminal @@ -303,6 +333,8 @@ DEVICE ($17) D=Device Type (MD, FD, IDE, etc.) E=Device Number (0..n) C=Device Attributes + H=Device Mode + L=Base I/O Adr Report the Device Type (Floppy, IDE, SD, etc.) and Device Number. Call does not perform any I/O and succeeds even if the device is in an error state. diff --git a/Source/HBIOS/Build.ps1 b/Source/HBIOS/Build.ps1 index e82b67aa..f2f5ee3f 100644 --- a/Source/HBIOS/Build.ps1 +++ b/Source/HBIOS/Build.ps1 @@ -19,7 +19,7 @@ param([string]$Platform = "", [string]$Config = "", [string]$RomSize = "512", [s # setup mechanism so that multiple configuration are not needed. When building for UNA, the pre-built # UNA BIOS is simply imbedded, it is not built here. # -$PlatformListZ80 = "SBC", "ZETA", "ZETA2", "RCZ80", "EZZ80", "UNA" +$PlatformListZ80 = "SBC", "ZETA", "ZETA2", "RCZ80", "RCZ280", "EZZ80", "UNA" $PlatformListZ180 = "N8", "MK4", "RCZ180", "SCZ180", "DYNO" # @@ -100,11 +100,12 @@ $env:PATH = $TasmPath + ';' + $CpmToolsPath + ';' + $env:PATH # Initialize working variables $OutDir = "../../Binary" # Output directory for final image file $RomFmt = "wbw_rom${RomSize}" # Location of files to imbed in ROM disk -$BlankROM = "Blank${RomSize}KB.dat" # An initial "empty" image for the ROM disk of propoer size +$BlankROM = "Blank${RomSize}KB.dat" # An initial "empty" image for the ROM disk of proper size $RomDiskFile = "RomDisk.tmp" # Temporary filename used to create ROM disk image $RomFile = "${OutDir}/${RomName}.rom" # Final name of ROM image $ComFile = "${OutDir}/${RomName}.com" # Final name of COM image (command line loadable HBIOS/CBIOS) $ImgFile = "${OutDir}/${RomName}.img" # Final name of IMG image (memory loadable HBIOS/CBIOS image) +$UpdFile = "${OutDir}/${RomName}.upd" # Final name of System ROM image # Select the proper CBIOS to include in the ROM. UNA is special. if ($Platform -eq "UNA") {$Bios = 'una'} else {$Bios = 'wbw'} @@ -226,6 +227,9 @@ foreach ($App in $RomApps) cpmcp -f $RomFmt $RomDiskFile ..\cpm22\cpm_${Bios}.sys 0:cpm.sys cpmcp -f $RomFmt $RomDiskFile ..\zsdos\zsys_${Bios}.sys 0:zsys.sys +# Set all the files in the ROM disk image to read only for extra protection under flash file system. +cpmchattr -f $RomFmt $RomDiskFile r 0:*.* + # # Finally, the individual binary components are concatenated together to produce # the final images. @@ -240,6 +244,7 @@ if ($Platform -eq "UNA") else { Concat 'hbios_rom.bin','osimg.bin','osimg1.bin','osimg.bin',$RomDiskFile $RomFile + Concat 'hbios_rom.bin','osimg.bin','osimg1.bin','osimg.bin' $UpdFile Concat 'hbios_app.bin','osimg_small.bin' $ComFile # Concat 'hbios_img.bin','osimg_small.bin' $ImgFile } diff --git a/Source/HBIOS/Build.sh b/Source/HBIOS/Build.sh index 86f8c05a..e63a9510 100755 --- a/Source/HBIOS/Build.sh +++ b/Source/HBIOS/Build.sh @@ -4,6 +4,7 @@ set -e CPMCP=../../Tools/`uname`/cpmcp +CPMCH=../../Tools/`uname`/cpmchattr timestamp=$(date +%Y-%m-%d) #timestamp="2020-02-24" @@ -13,9 +14,9 @@ if [ $1 == '-d' ] ; then diffdir=$1 shift if [ -f $diffdir/build.inc ] ; then - timestamp=$(grep TIMESTAMP $diffdir/build.inc | awk '{print $3}' | tr -d '\015"') + timestamp=$(grep TIMESTAMP $diffdir/build.inc | awk '{print $3}' | tr -d '\015"') echo diff build using $timestamp - fi + fi fi # positional arguments @@ -65,7 +66,10 @@ romfmt=wbw_rom${romsize} outdir=../../Binary echo "creating empty rom disk of size $romsize in $blankfile" -LANG=en_US.US-ASCII tr '\000' '\345' /dev/null +#LC_CTYPE=en_US.US-ASCII tr '\000' '\345' /dev/null +LC_ALL=en_US.US-ASCII tr '\000' '\345' build.inc ; RomWBW Configured for $platform $config $timestamp @@ -141,12 +145,16 @@ echo "copying systems to $romdiskfile" $CPMCP -f $romfmt $romdiskfile ../CPM22/cpm_$BIOS.sys 0:cpm.sys $CPMCP -f $romfmt $romdiskfile ../ZSDOS/zsys_$BIOS.sys 0:zsys.sys +echo "setting files in the ROM disk image to read only" +$CPMCH -f $romfmt $romdiskfile r 0:*.* + if [ $platform = UNA ] ; then cp osimg.bin $outdir/UNA_WBW_SYS.bin cp $romdiskfile $outdir/UNA_WBW_ROM$romsize.bin cat ../UBIOS/UNA-BIOS.BIN osimg.bin ../UBIOS/FSFAT.BIN $romdiskfile >$romname.rom else cat hbios_rom.bin osimg.bin osimg1.bin osimg.bin $romdiskfile >$romname.rom + cat hbios_rom.bin osimg.bin osimg1.bin osimg.bin >$romname.upd cat hbios_app.bin osimg_small.bin > $romname.com # cat hbios_img.bin osimg_small.bin > $romname.img fi diff --git a/Source/HBIOS/Config/DYNO_std.asm b/Source/HBIOS/Config/DYNO_std.asm index dccbf5a9..cc31253a 100644 --- a/Source/HBIOS/Config/DYNO_std.asm +++ b/Source/HBIOS/Config/DYNO_std.asm @@ -22,7 +22,7 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_dyno.asm" ; diff --git a/Source/HBIOS/Config/EZZ80_std.asm b/Source/HBIOS/Config/EZZ80_std.asm index 54f8aaf4..02796033 100644 --- a/Source/HBIOS/Config/EZZ80_std.asm +++ b/Source/HBIOS/Config/EZZ80_std.asm @@ -22,12 +22,16 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_ezz80.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; CPUOSC .SET 10000000 ; CPU OSC FREQ IN MHZ ; IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) ; PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/EZZ80_tz80.asm b/Source/HBIOS/Config/EZZ80_tz80.asm index 93a45e94..3d45393c 100644 --- a/Source/HBIOS/Config/EZZ80_tz80.asm +++ b/Source/HBIOS/Config/EZZ80_tz80.asm @@ -1,41 +1,45 @@ -; -;================================================================================================== -; EASY Z80 STANDARD CONFIGURATION -;================================================================================================== -; -; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE -; CFG_.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS -; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE -; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. -; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE _XXX.ASM AND SPECIFY -; YOUR FILE IN THE BUILD PROCESS. -; -; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. -; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO -; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON -; SETTINGS. -; -; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, -; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .EQU OPERATOR BELOW. ATTEMPTING -; TO REDEFINE A VALUE WITH .EQU BELOW WILL CAUSE TASM ERRORS! -; -; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO -; DIRECTORIES ABOVE THIS ONE). -; -#DEFINE PLATFORM_NAME "TINYZ80" -; -#include "cfg_ezz80.asm" -; -CPUOSC .SET 16000000 ; CPU OSC FREQ IN MHZ -; -IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) -; -PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) -; -EIPCENABLE .SET TRUE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION -; -CTCBASE .SET $10 ; CTC BASE I/O ADDRESS -LEDENABLE .SET TRUE ; ENABLES STATUS LED (SINGLE LED) -LEDPORT .SET $6E ; STATUS LED PORT ADDRESS -SIO0BASE .SET $18 ; SIO 0: REGISTERS BASE ADR -IDE0BASE .SET $90 ; IDE 0: IO BASE ADDRESS +; +;================================================================================================== +; EASY Z80 STANDARD CONFIGURATION +;================================================================================================== +; +; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE +; CFG_.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS +; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE +; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. +; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE _XXX.ASM AND SPECIFY +; YOUR FILE IN THE BUILD PROCESS. +; +; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. +; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO +; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON +; SETTINGS. +; +; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, +; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .EQU OPERATOR BELOW. ATTEMPTING +; TO REDEFINE A VALUE WITH .EQU BELOW WILL CAUSE TASM ERRORS! +; +; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO +; DIRECTORIES ABOVE THIS ONE). +; +#DEFINE PLATFORM_NAME "TINYZ80" +; +#include "cfg_ezz80.asm" +; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; +CPUOSC .SET 16000000 ; CPU OSC FREQ IN MHZ +; +IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) +; +PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +EIPCENABLE .SET TRUE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +; +CTCBASE .SET $10 ; CTC BASE I/O ADDRESS +LEDENABLE .SET TRUE ; ENABLES STATUS LED (SINGLE LED) +LEDPORT .SET $6E ; STATUS LED PORT ADDRESS +SIO0BASE .SET $18 ; SIO 0: REGISTERS BASE ADR +IDE0BASE .SET $90 ; IDE 0: IO BASE ADDRESS +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/MK4_std.asm b/Source/HBIOS/Config/MK4_std.asm index c838d873..027dcf36 100644 --- a/Source/HBIOS/Config/MK4_std.asm +++ b/Source/HBIOS/Config/MK4_std.asm @@ -22,7 +22,7 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_mk4.asm" ; @@ -37,7 +37,7 @@ CVDUENABLE .SET TRUE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) VGAENABLE .SET TRUE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .SET FDMODE_DIDE ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] +FDMODE .SET FDMODE_DIDE ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] ; IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) ; diff --git a/Source/HBIOS/Config/N8_std.asm b/Source/HBIOS/Config/N8_std.asm index 04b4b92e..25637a4e 100644 --- a/Source/HBIOS/Config/N8_std.asm +++ b/Source/HBIOS/Config/N8_std.asm @@ -22,7 +22,7 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_n8.asm" ; diff --git a/Source/HBIOS/Config/RCZ180_ext.asm b/Source/HBIOS/Config/RCZ180_ext.asm index 9c587ada..262e5507 100644 --- a/Source/HBIOS/Config/RCZ180_ext.asm +++ b/Source/HBIOS/Config/RCZ180_ext.asm @@ -1,6 +1,6 @@ ; ;================================================================================================== -; RC2014 Z180 STANDARD CONFIGURATION (EXTERNAL 512K RAM/ROM BANKED MEMORY MODULE) +; RC2014 Z180 STANDARD CONFIGURATION (EXTERNAL MMU ON 512K RAM/ROM BANKED MEMORY MODULE) ;================================================================================================== ; ; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE @@ -22,10 +22,13 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE PLATFORM_NAME "RC2014 (EXT MMU)" +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_rcz180.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; CPUOSC .SET 18432000 ; CPU OSC FREQ IN MHZ ; MEMMGR .SET MM_Z2 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] @@ -39,9 +42,13 @@ ASCIENABLE .SET TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) SIOENABLE .SET FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) ; +TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +; FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] +FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] ; IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) ; PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/RCZ180_nat.asm b/Source/HBIOS/Config/RCZ180_nat.asm index dc287783..0f7da479 100644 --- a/Source/HBIOS/Config/RCZ180_nat.asm +++ b/Source/HBIOS/Config/RCZ180_nat.asm @@ -1,6 +1,6 @@ ; ;================================================================================================== -; RC2014 Z180 STANDARD CONFIGURATION (NATIVE Z180 LINEAR MEMORY) +; RC2014 Z180 STANDARD CONFIGURATION (NATIVE Z180 MMU W/ LINEAR MEMORY) ;================================================================================================== ; ; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE @@ -22,10 +22,13 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE PLATFORM_NAME "RC2014 (NATIVE MMU)" +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_rcz180.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; CPUOSC .SET 18432000 ; CPU OSC FREQ IN MHZ ; MEMMGR .SET MM_Z180 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] @@ -39,9 +42,13 @@ ASCIENABLE .SET TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) SIOENABLE .SET FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) ; +TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +; FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] +FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] ; IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) ; PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/RCZ280_ext.asm b/Source/HBIOS/Config/RCZ280_ext.asm new file mode 100644 index 00000000..f38142f3 --- /dev/null +++ b/Source/HBIOS/Config/RCZ280_ext.asm @@ -0,0 +1,48 @@ +; +;================================================================================================== +; RC2014 Z280 STANDARD CONFIGURATION (EXTERNAL MMU ON 512K RAM/ROM BANKED MEMORY MODULE) +;================================================================================================== +; +; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE +; CFG_.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS +; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE +; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. +; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE _XXX.ASM AND SPECIFY +; YOUR FILE IN THE BUILD PROCESS. +; +; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. +; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO +; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON +; SETTINGS. +; +; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, +; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .EQU OPERATOR BELOW. ATTEMPTING +; TO REDEFINE A VALUE WITH .EQU BELOW WILL CAUSE TASM ERRORS! +; +; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO +; DIRECTORIES ABOVE THIS ONE). +; +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +; +#include "cfg_rcz280.asm" +; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; +CPUOSC .SET 24000000 ; CPU OSC FREQ IN MHZ +; +INTMODE .SET 1 +; +Z280_MEMWAIT .SET 0 ; Z280: MEMORY WAIT STATES (0-3) +Z280_IOWAIT .SET 1 ; Z280: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3) +Z280_INTWAIT .SET 0 ; Z280: INT ACK WAIT STATUS (0-3) +; +Z2UENABLE .SET TRUE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +UARTENABLE .SET TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) +ACIAENABLE .SET TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) +SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) +; +IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) +; +PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/RCZ280_nat.asm b/Source/HBIOS/Config/RCZ280_nat.asm new file mode 100644 index 00000000..bcc119f4 --- /dev/null +++ b/Source/HBIOS/Config/RCZ280_nat.asm @@ -0,0 +1,52 @@ +; +;================================================================================================== +; RC2014 Z280 STANDARD CONFIGURATION (NATIVE Z280 MMU W/ LINEAR MEMORY) +;================================================================================================== +; +; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE +; CFG_.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS +; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE +; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. +; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE _XXX.ASM AND SPECIFY +; YOUR FILE IN THE BUILD PROCESS. +; +; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. +; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO +; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON +; SETTINGS. +; +; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, +; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .EQU OPERATOR BELOW. ATTEMPTING +; TO REDEFINE A VALUE WITH .EQU BELOW WILL CAUSE TASM ERRORS! +; +; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO +; DIRECTORIES ABOVE THIS ONE). +; +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +; +#include "cfg_rcz280.asm" +; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; +CPUOSC .SET 24000000 ; CPU OSC FREQ IN MHZ +; +MEMMGR .SET MM_Z280 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180|Z280] +; +INTMODE .SET 3 +; +Z280_MEMWAIT .SET 0 ; Z280: MEMORY WAIT STATES (0-3) +Z280_IOWAIT .SET 1 ; Z280: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3) +Z280_INTWAIT .SET 0 ; Z280: INT ACK WAIT STATUS (0-3) +; +Z2UENABLE .SET TRUE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +UARTENABLE .SET TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) +ACIAENABLE .SET TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) +SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) +; +IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) +; +PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) +; +Z2UOSCEXT .SET TRUE ; Z2U: USE EXTERNAL OSCILLATOR diff --git a/Source/HBIOS/Config/RCZ80_duart.asm b/Source/HBIOS/Config/RCZ80_duart.asm new file mode 100644 index 00000000..7879d0ee --- /dev/null +++ b/Source/HBIOS/Config/RCZ80_duart.asm @@ -0,0 +1,36 @@ +; +;================================================================================================== +; RC2014 Z80 CONFIGURATION W/ DUART +;================================================================================================== +; +; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE +; CFG_.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS +; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE +; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. +; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE _XXX.ASM AND SPECIFY +; YOUR FILE IN THE BUILD PROCESS. +; +; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. +; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO +; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON +; SETTINGS. +; +; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, +; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .EQU OPERATOR BELOW. ATTEMPTING +; TO REDEFINE A VALUE WITH .EQU BELOW WILL CAUSE TASM ERRORS! +; +; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO +; DIRECTORIES ABOVE THIS ONE). +; +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +; +#DEFINE PLATFORM_NAME "RC2014 (DUART)" +; +#include "Config/RCZ80_std.asm" +; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; +DUARTENABLE .SET TRUE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +DUARTCNT .SET 1 ; DUART: NUMBER OF CHIPS TO DETECT (1-2) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/RCZ80_kio.asm b/Source/HBIOS/Config/RCZ80_kio.asm index a83052f4..82553bae 100644 --- a/Source/HBIOS/Config/RCZ80_kio.asm +++ b/Source/HBIOS/Config/RCZ80_kio.asm @@ -22,25 +22,31 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define PLATFORM_NAME "RC2014 (KIO)" +#DEFINE PLATFORM_NAME "RC2014 (KIO)" ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "Config/RCZ80_std.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; INTMODE .SET 2 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 ; KIOENABLE .SET TRUE ; ENABLE ZILOG KIO SUPPORT ; CTCENABLE .SET TRUE ; ENABLE ZILOG CTC SUPPORT +CTCTIMER .SET TRUE ; ENABLE CTC PERIODIC TIMER CTCBASE .SET KIOBASE+$04 ; CTC BASE I/O ADDRESS ; ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) SIOCNT .SET 1 ; SIO: NUMBER OF CHIPS TO DETECT (1-2), 2 CHANNELS PER CHIP -SIO0MODE .SET SIOMODE_EZZ80 ; SIO 0: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] +SIO0MODE .SET SIOMODE_STD ; SIO 0: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO0BASE .SET KIOBASE+$08 ; SIO 0: REGISTERS BASE ADR -SIO0CTCC .SET 0 ; SIO 0: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE SIO0ACLK .SET 1843200 ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 +SIO0ACTCC .SET 0 ; SIO 0A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO0BCLK .SET 1843200 ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 +SIO0BCTCC .SET 1 ; SIO 0B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/RCZ80_mt.asm b/Source/HBIOS/Config/RCZ80_mt.asm index 1e49c5d3..5e9857e2 100644 --- a/Source/HBIOS/Config/RCZ80_mt.asm +++ b/Source/HBIOS/Config/RCZ80_mt.asm @@ -22,11 +22,15 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; -#define PLATFORM_NAME "RC2014 (MT)" +#DEFINE PLATFORM_NAME "RC2014 (MT)" ; #include "Config/RCZ80_std.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; +TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) +; SDENABLE .SET TRUE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) -SDMODE .SET SDMODE_MT ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4|SC|MT] diff --git a/Source/HBIOS/Config/RCZ80_std.asm b/Source/HBIOS/Config/RCZ80_std.asm index da88345f..dbe7d3ac 100644 --- a/Source/HBIOS/Config/RCZ80_std.asm +++ b/Source/HBIOS/Config/RCZ80_std.asm @@ -22,19 +22,26 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_rcz80.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; CPUOSC .SET 7372800 ; CPU OSC FREQ IN MHZ ; UARTENABLE .SET TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) ACIAENABLE .SET TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) ; +TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) +; FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] +FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] ; IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) ; PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/RCZ80_zrc.asm b/Source/HBIOS/Config/RCZ80_zrc.asm new file mode 100644 index 00000000..3b4c70f8 --- /dev/null +++ b/Source/HBIOS/Config/RCZ80_zrc.asm @@ -0,0 +1,49 @@ +; +;================================================================================================== +; RC2014 Z80 ZRC CONFIGURATION +;================================================================================================== +; +; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE +; CFG_.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS +; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE +; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. +; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE _XXX.ASM AND SPECIFY +; YOUR FILE IN THE BUILD PROCESS. +; +; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. +; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO +; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON +; SETTINGS. +; +; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, +; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .EQU OPERATOR BELOW. ATTEMPTING +; TO REDEFINE A VALUE WITH .EQU BELOW WILL CAUSE TASM ERRORS! +; +; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO +; DIRECTORIES ABOVE THIS ONE). +; +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +; +#include "cfg_rcz80.asm" +; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; +CPUOSC .SET 7372800 ; CPU OSC FREQ IN MHZ +; +MEMMGR .SET MM_ZRC ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +; +UARTENABLE .SET TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) +ACIAENABLE .SET TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) +SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) +; +TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) +; +FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) +FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +; +IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) +; +PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/SBC_max.asm b/Source/HBIOS/Config/SBC_max.asm new file mode 100644 index 00000000..ab57620a --- /dev/null +++ b/Source/HBIOS/Config/SBC_max.asm @@ -0,0 +1,65 @@ +; +;================================================================================================== +; SBC MAXIMUM CONFIGURATION +;================================================================================================== +; +; THIS CONFIGURATION FILE IS *NOT* MEANT TO GENERATE A FUNCTIONAL ROM. +; IT IS USED TO HELP TEST BUILDS WITH MOST FEATURES ENABLED. +; +; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE +; CFG_.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS +; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE +; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. +; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE _XXX.ASM AND SPECIFY +; YOUR FILE IN THE BUILD PROCESS. +; +; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. +; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO +; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON +; SETTINGS. +; +; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, +; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .SET OPERATOR BELOW. ATTEMPTING +; TO REDEFINE A VALUE WITH .SET BELOW WILL CAUSE TASM ERRORS! +; +; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO +; DIRECTORIES ABOVE THIS ONE). +; +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +; +#include "cfg_sbc.asm" +; +BATCOND .SET TRUE ; ENABLE LOW BATTERY WARNING MESSAGE +HBIOS_MUTEX .SET TRUE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) +USELZSA2 .SET TRUE ; ENABLE FONT COMPRESSION +; +KIOENABLE .SET TRUE ; ENABLE ZILOG KIO SUPPORT +; +DIAGENABLE .SET TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT +; +DSKYENABLE .SET TRUE ; ENABLES DSKY (DO NOT COMBINE WITH PPIDE) +; +DSRTCENABLE .SET TRUE ; DSRTC: ENABLE DS-1302 CLOCK DRIVER (DSRTC.ASM) +; +UARTENABLE .SET TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) +; +SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) +; +VDUENABLE .SET TRUE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) +CVDUENABLE .SET TRUE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) +TMSENABLE .SET TRUE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +VGAENABLE .SET TRUE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) +; +FDENABLE .SET TRUE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) +; +RFENABLE .SET TRUE ; RF: ENABLE RAM FLOPPY DRIVER +; +IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) +; +PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +SDENABLE .SET TRUE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) +; +PRPENABLE .SET TRUE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) +; +AY38910ENABLE .SET TRUE ; AY: AY-3-8910 / YM2149 SOUND DRIVER diff --git a/Source/HBIOS/Config/SBC_simh.asm b/Source/HBIOS/Config/SBC_simh.asm index b2088dfe..fa3e8cdd 100644 --- a/Source/HBIOS/Config/SBC_simh.asm +++ b/Source/HBIOS/Config/SBC_simh.asm @@ -22,7 +22,7 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #DEFINE PLATFORM_NAME "SBC (simh)" ; diff --git a/Source/HBIOS/Config/SBC_std.asm b/Source/HBIOS/Config/SBC_std.asm index 16acc300..b68e80c1 100644 --- a/Source/HBIOS/Config/SBC_std.asm +++ b/Source/HBIOS/Config/SBC_std.asm @@ -22,7 +22,7 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_sbc.asm" ; @@ -33,7 +33,7 @@ CVDUENABLE .SET TRUE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) VGAENABLE .SET TRUE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .SET FDMODE_DIO3 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] +FDMODE .SET FDMODE_DIO3 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] ; IDEENABLE .SET FALSE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) ; diff --git a/Source/HBIOS/Config/SCZ180_126.asm b/Source/HBIOS/Config/SCZ180_126.asm index 1da05c4b..04a7859a 100644 --- a/Source/HBIOS/Config/SCZ180_126.asm +++ b/Source/HBIOS/Config/SCZ180_126.asm @@ -22,12 +22,14 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define PLATFORM_NAME "SC126" +#DEFINE PLATFORM_NAME "SC126" ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_scz180.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; CPUOSC .SET 18432000 ; CPU OSC FREQ IN MHZ ; Z180_CLKDIV .SET 1 ; Z180: CHK DIV: 0=OSC/2, 1=OSC, 2=OSC*2 @@ -41,8 +43,10 @@ ASCIENABLE .SET TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) SIOENABLE .SET FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) ; +TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +; FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] +FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] ; IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) ; @@ -50,3 +54,5 @@ PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) ; SDENABLE .SET TRUE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) SDCNT .SET 1 ; SD: NUMBER OF SD CARD DEVICES (1-2), FOR DSD & SC ONLY +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/SCZ180_130.asm b/Source/HBIOS/Config/SCZ180_130.asm index cf84881b..0793f77f 100644 --- a/Source/HBIOS/Config/SCZ180_130.asm +++ b/Source/HBIOS/Config/SCZ180_130.asm @@ -22,12 +22,14 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define PLATFORM_NAME "SC130" +#DEFINE PLATFORM_NAME "SC130" ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_scz180.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; CPUOSC .SET 18432000 ; CPU OSC FREQ IN MHZ ; Z180_CLKDIV .SET 1 ; Z180: CHK DIV: 0=OSC/2, 1=OSC, 2=OSC*2 @@ -43,12 +45,14 @@ DIAGENABLE .SET FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DSRTCENABLE .SET FALSE ; DSRTC: ENABLE DS-1302 CLOCK DRIVER (DSRTC.ASM) INTRTCENABLE .SET TRUE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) ; -UARTENABLE .SET FALSE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) +UARTENABLE .SET TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) ASCIENABLE .SET TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) SIOENABLE .SET FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) ; -FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) +TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +; +FDENABLE .SET FALSE ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] ; IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) @@ -56,3 +60,5 @@ IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) ; SDENABLE .SET TRUE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/SCZ180_131.asm b/Source/HBIOS/Config/SCZ180_131.asm index c3b75a80..5c400347 100644 --- a/Source/HBIOS/Config/SCZ180_131.asm +++ b/Source/HBIOS/Config/SCZ180_131.asm @@ -22,12 +22,14 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define PLATFORM_NAME "SC131" +#DEFINE PLATFORM_NAME "SC131" ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_scz180.asm" ; +CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +; CPUOSC .SET 18432000 ; CPU OSC FREQ IN MHZ ; Z180_CLKDIV .SET 1 ; Z180: CHK DIV: 0=OSC/2, 1=OSC, 2=OSC*2 @@ -49,10 +51,12 @@ ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) SIOENABLE .SET FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) ; FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] +FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] ; IDEENABLE .SET FALSE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) ; PPIDEENABLE .SET FALSE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) ; SDENABLE .SET TRUE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) +; +PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/Config/SCZ180_140.asm b/Source/HBIOS/Config/SCZ180_140.asm new file mode 100644 index 00000000..2bd0b7c1 --- /dev/null +++ b/Source/HBIOS/Config/SCZ180_140.asm @@ -0,0 +1,56 @@ +; +;================================================================================================== +; SC140 STANDARD CONFIGURATION +;================================================================================================== +; +; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE +; CFG_.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS +; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE +; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. +; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE _XXX.ASM AND SPECIFY +; YOUR FILE IN THE BUILD PROCESS. +; +; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. +; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO +; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON +; SETTINGS. +; +; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, +; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .EQU OPERATOR BELOW. ATTEMPTING +; TO REDEFINE A VALUE WITH .EQU BELOW WILL CAUSE TASM ERRORS! +; +; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO +; DIRECTORIES ABOVE THIS ONE). +; +#DEFINE PLATFORM_NAME "SC140" +; +#include "cfg_scz180.asm" +; +CPUOSC .SET 18432000 ; CPU OSC FREQ IN MHZ +; +Z180_CLKDIV .SET 1 ; Z180: CHK DIV: 0=OSC/2, 1=OSC, 2=OSC*2 +Z180_MEMWAIT .SET 0 ; Z180: MEMORY WAIT STATES (0-3) +Z180_IOWAIT .SET 1 ; Z180: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3) +; +HBIOS_MUTEX .SET FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) +; +LEDENABLE .SET TRUE ; ENABLE STATUS LED (SINGLE LED) +; +DIAGENABLE .SET TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT +; +DSRTCENABLE .SET TRUE ; DSRTC: ENABLE DS-1302 CLOCK DRIVER (DSRTC.ASM) +; +ASCIENABLE .SET TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) +; +ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) +; +SIOENABLE .SET FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) +; +FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) +FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3] +; +IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) +; +PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +; +SDENABLE .SET TRUE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) diff --git a/Source/HBIOS/Config/UNA_std.asm b/Source/HBIOS/Config/UNA_std.asm index c722c7af..ee28f83a 100644 --- a/Source/HBIOS/Config/UNA_std.asm +++ b/Source/HBIOS/Config/UNA_std.asm @@ -22,6 +22,6 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_una.asm" diff --git a/Source/HBIOS/Config/ZETA2_std.asm b/Source/HBIOS/Config/ZETA2_std.asm index 0c434c57..26b9a1da 100644 --- a/Source/HBIOS/Config/ZETA2_std.asm +++ b/Source/HBIOS/Config/ZETA2_std.asm @@ -22,7 +22,7 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_zeta2.asm" ; diff --git a/Source/HBIOS/Config/ZETA_std.asm b/Source/HBIOS/Config/ZETA_std.asm index cfc82665..06ae8cbe 100644 --- a/Source/HBIOS/Config/ZETA_std.asm +++ b/Source/HBIOS/Config/ZETA_std.asm @@ -22,7 +22,7 @@ ; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO ; DIRECTORIES ABOVE THIS ONE). ; -#define BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT +#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON OR AUTO BOOT ; #include "cfg_zeta.asm" ; diff --git a/Source/HBIOS/Makefile b/Source/HBIOS/Makefile index 294ddf1a..935f7b2d 100644 --- a/Source/HBIOS/Makefile +++ b/Source/HBIOS/Makefile @@ -1,26 +1,33 @@ -OBJECTS = +ifndef ROM_CONFIG + ROM_CONFIG=std +endif -ifeq (1,1) -OBJECTS += DYNO_std.rom DYNO_std.com -OBJECTS += EZZ80_std.rom EZZ80_std.com -OBJECTS += EZZ80_tz80.rom EZZ80_tz80.com -OBJECTS += MK4_std.rom MK4_std.com -OBJECTS += N8_std.rom N8_std.com -OBJECTS += RCZ180_ext.rom RCZ180_ext.com -OBJECTS += RCZ180_nat.rom RCZ180_nat.com -OBJECTS += RCZ80_kio.rom RCZ80_kio.com -OBJECTS += RCZ80_mt.rom RCZ80_mt.com -OBJECTS += RCZ80_std.rom RCZ80_std.com -OBJECTS += SBC_simh.rom SBC_simh.com -OBJECTS += SBC_std.rom SBC_std.com -OBJECTS += SCZ180_126.rom SCZ180_126.com -OBJECTS += SCZ180_130.rom SCZ180_130.com -OBJECTS += SCZ180_131.rom SCZ180_131.com -OBJECTS += UNA_std.rom -OBJECTS += ZETA_std.rom ZETA_std.com -OBJECTS += ZETA2_std.rom ZETA2_std.com +ifdef ROM_PLATFORM + OBJECTS = ${ROM_PLATFORM}_${ROM_CONFIG}.rom ${ROM_PLATFORM}_${ROM_CONFIG}.com ${ROM_PLATFORM}_${ROM_CONFIG}.upd else -OBJECTS += ZETA2_std.rom ZETA2_std.com + OBJECTS += DYNO_std.rom DYNO_std.com DYNO_std.upd + OBJECTS += EZZ80_std.rom EZZ80_std.com EZZ80_std.upd + OBJECTS += EZZ80_tz80.rom EZZ80_tz80.com EZZ80_tz80.upd + OBJECTS += MK4_std.rom MK4_std.com MK4_std.upd + OBJECTS += N8_std.rom N8_std.com N8_std.upd + OBJECTS += RCZ180_ext.rom RCZ180_ext.com RCZ180_ext.upd + OBJECTS += RCZ180_nat.rom RCZ180_nat.com RCZ180_nat.upd + OBJECTS += RCZ280_ext.rom RCZ280_ext.com RCZ280_ext.upd + OBJECTS += RCZ280_nat.rom RCZ280_nat.com RCZ280_nat.upd + OBJECTS += RCZ80_kio.rom RCZ80_kio.com RCZ80_kio.upd + OBJECTS += RCZ80_mt.rom RCZ80_mt.com RCZ80_mt.upd + OBJECTS += RCZ80_duart.rom RCZ80_duart.com RCZ80_duart.upd + OBJECTS += RCZ80_std.rom RCZ80_std.com RCZ80_std.upd + OBJECTS += RCZ80_zrc.rom RCZ80_zrc.com RCZ80_zrc.upd + OBJECTS += SBC_simh.rom SBC_simh.com SBC_simh.upd + OBJECTS += SBC_std.rom SBC_std.com SBC_std.upd + OBJECTS += SCZ180_126.rom SCZ180_126.com SCZ180_126.upd + OBJECTS += SCZ180_130.rom SCZ180_130.com SCZ180_130.upd + OBJECTS += SCZ180_131.rom SCZ180_131.com SCZ180_131.upd + OBJECTS += SCZ180_140.rom SCZ180_140.com SCZ180_140.upd + OBJECTS += UNA_std.rom + OBJECTS += ZETA_std.rom ZETA_std.com ZETA_std.upd + OBJECTS += ZETA2_std.rom ZETA2_std.com ZETA2_std.upd endif MOREDIFF = camel80.bin game.bin hbios_rom.bin nascom.bin prefix.bin usrrom.bin \ @@ -28,7 +35,7 @@ MOREDIFF = camel80.bin game.bin hbios_rom.bin nascom.bin prefix.bin usrrom.bin \ eastaegg.bin hbios_img.bin imgpad.bin osimg.bin tastybasic.bin \ game.bin usrrom.bin -SUBDIRS = +SUBDIRS = DEST = ../../Binary TOOLS =../../Tools OTHERS = *.img *.rom *.com *.bin *.z80 cpm.sys zsys.sys Build.inc RomDisk.tmp font*.asm *.dat diff --git a/Source/HBIOS/acia.asm b/Source/HBIOS/acia.asm index 38947a61..c1053dca 100644 --- a/Source/HBIOS/acia.asm +++ b/Source/HBIOS/acia.asm @@ -57,11 +57,6 @@ ACIA_ACIA .EQU 1 ACIA_RTSON .EQU %00000000 ; BIT MASK TO ASSERT RTS ACIA_RTSOFF .EQU %01000000 ; BIT MASK TO DEASSERT RTS ; -#IF (INTMODE > 1) - .ECHO "*** ERROR: UNSUPPORTED INTMODE FOR ACIA DRIVER!!!\n" - !!! ; FORCE AN ASSEMBLY ERROR -#ENDIF -; ; ; ACIA_PREINIT: @@ -120,17 +115,12 @@ ACIA_INITUNIT: CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST #ENDIF ; -#IF (INTMODE > 1) - .ECHO "*** ERROR: ACIA DEVICE DOES NOT SUPPORT INTMODE 2!!!\n" - !!! ; FORCE AN ASSEMBLY ERROR -#ENDIF -; - ; IT IS EASY TO SPECIFY A SERIAL CONFIG THAT CANNOT BE IMPLEMENTED - ; DUE TO THE CONSTRAINTS OF THE ACIA. HERE WE FORCE A GENERIC - ; FAILSAFE CONFIG ONTO THE CHANNEL. IF THE SUBSEQUENT "REAL" - ; CONFIG FAILS, AT LEAST THE CHIP WILL BE ABLE TO SPIT DATA OUT - ; AT A RATIONAL BAUD/DATA/PARITY/STOP CONFIG. - CALL ACIA_INITSAFE + ; IT IS EASY TO SPECIFY A SERIAL CONFIG THAT CANNOT BE IMPLEMENTED + ; DUE TO THE CONSTRAINTS OF THE ACIA. HERE WE FORCE A GENERIC + ; FAILSAFE CONFIG ONTO THE CHANNEL. IF THE SUBSEQUENT "REAL" + ; CONFIG FAILS, AT LEAST THE CHIP WILL BE ABLE TO SPIT DATA OUT + ; AT A RATIONAL BAUD/DATA/PARITY/STOP CONFIG. + CALL ACIA_INITSAFE ; ; SET DEFAULT CONFIG LD DE,-1 ; LEAVE CONFIG ALONE @@ -158,18 +148,18 @@ ACIA_INIT1: ; ; INTERRUPT HANDLERS ; -#IF (INTMODE == 0) +#IF (INTMODE != 1) ; ; NO INTERRUPT HANDLERS UNDER INTMODE 0. GENERATE A PANIC ; IF SOMETHING TRIES TO CALL THEM. ; ACIA0_INT: ACIA1_INT: - CALL PANIC + CALL PANIC ; NO RETURN ; #ENDIF ; -#IF (INTMODE > 0) +#IF (INTMODE == 1) ; ACIA0_INT: LD IY,ACIA0_CFG ; POINT TO ACIA0 CFG @@ -263,7 +253,7 @@ ACIA_FNTBL: ; ; ; -#IF (INTMODE == 0) +#IF (INTMODE != 1) ; ACIA_IN: CALL ACIA_IST ; CHAR WAITING? @@ -336,7 +326,7 @@ ACIA_OUT: ; ; ; -#IF (INTMODE == 0) +#IF (INTMODE != 1) ; ACIA_IST: LD C,(IY+3) ; STATUS PORT @@ -403,6 +393,7 @@ ACIA_INITDEVX: LD D,(IY+5) ; HIGH BYTE ; ACIA_INITDEV1: + LD (ACIA_NEWCFG),DE ; SAVE NEW CONFIG ; #IF (ACIADEBUG) PUSH DE @@ -498,20 +489,26 @@ ACIA_WSTBL: .DB %00011110 ; 7/E/2 ACIA_INITWS2: - LD A,B ; PUT FANAL VALUE IN A - DEC A ; ZERO INDEX ADJUSTMENT - RLA ; MOVE BITS TO - RLA ; ... PROPER LOCATION - OR C ; COMBINE WITH WORKING VALUE - JR ACIA_INITGO + LD A,B ; PUT FANAL VALUE IN A + DEC A ; ZERO INDEX ADJUSTMENT + RLA ; MOVE BITS TO + RLA ; ... PROPER LOCATION + OR C ; COMBINE WITH WORKING VALUE +; + ; SAVE CONFIG PERMANENTLY NOW + LD DE,(ACIA_NEWCFG) ; GET NEW CONFIG BACK + LD (IY+4),E ; SAVE LOW WORD + LD (IY+5),D ; SAVE HI WORD +; + JR ACIA_INITGO ; ACIA_INITSAFE: LD A,%00010110 ; DEFAULT CONFIG ; ACIA_INITGO: ; -#IF (INTMODE > 0) - OR %10000000 ; ENABLE RCV INT +#IF (INTMODE == 1) + OR %10000000 ; ENABLE RCV INT #ENDIF ; LD (ACIA_CMD),A ; SAVE SHADOW REGISTER @@ -530,7 +527,7 @@ ACIA_INITGO: LD A,(ACIA_CMD) ; RESTORE CONFIG VALUE OUT (C),A ; DO IT ; -#IF (INTMODE > 0) +#IF (INTMODE == 1) ; ; RESET THE RECEIVE BUFFER LD E,(IY+6) @@ -571,21 +568,16 @@ ACIA_DEVICE: LD D,CIODEV_ACIA ; D := DEVICE TYPE LD E,(IY) ; E := PHYSICAL UNIT LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+3) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; ; ACIA DETECTION ROUTINE ; -; NOTE THAT THE ACIA MODULES ONLY QUALIFY ADDRESS BITS 7 & 6, SO -; THE ACIA'S TWO PORTS APPEAR REPEATEDLY OVER AN ADDRESS RANGE -; OF $40 STARTING FROM THE REAL BASE PORT. -; WE TAKE ADVANTAGE OF THIS TO AVOID CONFLICTING WITH SIO -; AND COMPACT FLASH MODULES DURING DETECTION PROBES. -; ACIA_DETECT: - LD A,(IY+3) ; BASE PORT ADDRESS - ADD A,$20 ; OFFSET (SEE ABOVE) - LD C,A ; PUT IN C FOR I/O + LD A,(IY+3) ; BASE PORT ADDRESS + LD C,A ; PUT IN C FOR I/O CALL ACIA_DETECT2 ; CHECK IT JR Z,ACIA_DETECT1 ; FOUND IT, RECORD IT LD A,ACIA_NONE ; NOTHING FOUND @@ -605,6 +597,7 @@ ACIA_DETECT2: RET NZ ; RETURN IF NOT ZERO LD A,$02 ; CLEAR MASTER RESET OUT (C),A ; DO IT + IN A,(C) ; GET STATUS AGAIN ; CHECK FOR EXPECTED BITS: ; TDRE=1, DCD & CTS = 0 AND %00001110 ; BIT MASK FOR "STABLE" BITS @@ -659,9 +652,10 @@ ACIA_STR_ACIA .DB "ACIA$" ; WORKING VARIABLES ; ACIA_DEV .DB 0 ; DEVICE NUM USED DURING INIT -ACIA_CMD .DB 0 ; COMMAND PORT SHADOW REGISTER +ACIA_CMD .DB 0 ; COMMAND PORT SHADOW REGISTER +ACIA_NEWCFG .DW 0 ; TEMP STORE FOR NEW CFG ; -#IF (INTMODE == 0) +#IF (INTMODE != 1) ; ACIA0_RCVBUF .EQU 0 ACIA1_RCVBUF .EQU 0 @@ -674,7 +668,7 @@ ACIA0_RCVBUF: ACIA0_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER ACIA0_HD .DW ACIA0_BUF ; BUFFER HEAD POINTER ACIA0_TL .DW ACIA0_BUF ; BUFFER TAIL POINTER -ACIA0_BUF .FILL 32,0 ; RECEIVE RING BUFFER +ACIA0_BUF .FILL ACIA_BUFSZ,0 ; RECEIVE RING BUFFER ACIA0_BUFEND .EQU $ ; END OF BUFFER ACIA0_BUFSZ .EQU $ - ACIA0_BUF ; SIZE OF RING BUFFER ; @@ -684,7 +678,7 @@ ACIA1_RCVBUF: ACIA1_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER ACIA1_HD .DW ACIA1_BUF ; BUFFER HEAD POINTER ACIA1_TL .DW ACIA1_BUF ; BUFFER TAIL POINTER -ACIA1_BUF .FILL 32,0 ; RECEIVE RING BUFFER +ACIA1_BUF .FILL ACIA_BUFSZ,0 ; RECEIVE RING BUFFER ACIA1_BUFEND .EQU $ ; END OF BUFFER ACIA1_BUFSZ .EQU $ - ACIA1_BUF ; SIZE OF RING BUFFER ; diff --git a/Source/HBIOS/asci.asm b/Source/HBIOS/asci.asm index 26a71d87..dc05caba 100644 --- a/Source/HBIOS/asci.asm +++ b/Source/HBIOS/asci.asm @@ -87,7 +87,7 @@ ASCI1_IVT .EQU IVT(INT_SER1) ASCI_PREINIT: ; ; SETUP THE DISPATCH TABLE ENTRIES -; NOTE: INTS WILL BE DISABLED WHEN PREINIT IS CALLED AND THEY MUST REMIAIN +; NOTE: INTS WILL BE DISABLED WHEN PREINIT IS CALLED AND THEY MUST REMAIN ; DISABLED. ; LD B,ASCI_CFGCNT ; LOOP CONTROL @@ -575,6 +575,8 @@ ASCI_DEVICE: LD D,CIODEV_ASCI ; D := DEVICE TYPE LD E,(IY) ; E := PHYSICAL UNIT LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+3) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -776,7 +778,7 @@ ASCI0_RCVBUF: ASCI0_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER ASCI0_HD .DW ASCI0_BUF ; BUFFER HEAD POINTER ASCI0_TL .DW ASCI0_BUF ; BUFFER TAIL POINTER -ASCI0_BUF .FILL 32,0 ; RECEIVE RING BUFFER +ASCI0_BUF .FILL ASCI_BUFSZ,0 ; RECEIVE RING BUFFER ASCI0_BUFEND .EQU $ ; END OF BUFFER ASCI0_BUFSZ .EQU $ - ASCI0_BUF ; SIZE OF RING BUFFER ; @@ -784,7 +786,7 @@ ASCI1_RCVBUF: ASCI1_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER ASCI1_HD .DW ASCI1_BUF ; BUFFER HEAD POINTER ASCI1_TL .DW ASCI1_BUF ; BUFFER TAIL POINTER -ASCI1_BUF .FILL 32,0 ; RECEIVE RING BUFFER +ASCI1_BUF .FILL ASCI_BUFSZ,0 ; RECEIVE RING BUFFER ASCI1_BUFEND .EQU $ ; END OF BUFFER ASCI1_BUFSZ .EQU $ - ASCI1_BUF ; SIZE OF RING BUFFER ; @@ -794,8 +796,32 @@ ASCI1_BUFSZ .EQU $ - ASCI1_BUF ; SIZE OF RING BUFFER ; ASCI_CFG: ; +#IF (ASCISWAP) +; +ASCI1_CFG: + ; ASCI CHANNEL B CONFIG + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; ASCI TYPE (SET DURING INIT) + .DB 1 ; MODULE ID + .DB ASCI1_BASE ; BASE PORT + .DW ASCI1CFG ; LINE CONFIGURATION + .DW ASCI1_RCVBUF ; POINTER TO RCV BUFFER STRUCT +; +ASCI_CFGSIZ .EQU $ - ASCI_CFG ; SIZE OF ONE CFG TABLE ENTRY +; +ASCI0_CFG: + ; ASCI CHANNEL A CONFIG + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; ASCI TYPE (SET DURING INIT) + .DB 0 ; MODULE ID + .DB ASCI0_BASE ; BASE PORT + .DW ASCI0CFG ; LINE CONFIGURATION + .DW ASCI0_RCVBUF ; POINTER TO RCV BUFFER STRUCT +; +#ELSE +; ASCI0_CFG: - ; ASCI MODULE A CONFIG + ; ASCI CHANNEL A CONFIG .DB 0 ; DEVICE NUMBER (SET DURING INIT) .DB 0 ; ASCI TYPE (SET DURING INIT) .DB 0 ; MODULE ID @@ -806,7 +832,7 @@ ASCI0_CFG: ASCI_CFGSIZ .EQU $ - ASCI_CFG ; SIZE OF ONE CFG TABLE ENTRY ; ASCI1_CFG: - ; ASCI MODULE B CONFIG + ; ASCI CHANNEL B CONFIG .DB 0 ; DEVICE NUMBER (SET DURING INIT) .DB 0 ; ASCI TYPE (SET DURING INIT) .DB 1 ; MODULE ID @@ -814,4 +840,7 @@ ASCI1_CFG: .DW ASCI1CFG ; LINE CONFIGURATION .DW ASCI1_RCVBUF ; POINTER TO RCV BUFFER STRUCT ; +#ENDIF +; +; ASCI_CFGCNT .EQU ($ - ASCI_CFG) / ASCI_CFGSIZ diff --git a/Source/HBIOS/audio.inc b/Source/HBIOS/audio.inc new file mode 100644 index 00000000..b6365494 --- /dev/null +++ b/Source/HBIOS/audio.inc @@ -0,0 +1,75 @@ +#IF AUDIOTRACE +#DEFINE AUDTRACE(STR) PUSH DE \ LD DE, STR \ CALL WRITESTR \ POP DE +#DEFINE AUDTRACE_A CALL PRTHEXBYTE +#DEFINE AUDTRACE_B PUSH AF \ LD A, B \ CALL PRTHEXBYTE \ POP AF +#DEFINE AUDTRACE_D PUSH AF \ LD A, D \ CALL PRTHEXBYTE \ POP AF +#DEFINE AUDTRACE_E PUSH AF \ LD A, E \ CALL PRTHEXBYTE \ POP AF +#DEFINE AUDTRACE_L PUSH AF \ LD A, L \ CALL PRTHEXBYTE \ POP AF +#DEFINE AUDTRACE_HL CALL PRTHEXWORDHL +#DEFINE AUDTRACE_BC PUSH HL \ PUSH BC \ POP HL \ CALL PRTHEXWORDHL \ POP HL +#DEFINE AUDTRACE_DE PUSH HL \ PUSH DE \ POP HL \ CALL PRTHEXWORDHL \ POP HL +#DEFINE AUDTRACE_IY PUSH HL \ PUSH IY \ POP HL \ CALL PRTHEXWORDHL \ POP HL + +#DEFINE AUDDEBUG(S) push hl \ CALL PRTSTRD \ .TEXT S \ .TEXT "$" \ pop hl ; $$$$$$ PRINT STRING S TO CONSOLE - PRTD("HELLO") - NO TRAILING $ REQUIRED + +#DEFINE AUDTRACE_CR AUDDEBUG("\r\n$") + +#ELSE +#DEFINE AUDTRACE(S) +#DEFINE AUDTRACE_A +#DEFINE AUDTRACE_B +#DEFINE AUDTRACE_D +#DEFINE AUDTRACE_E +#DEFINE AUDTRACE_L +#DEFINE AUDTRACE_BC +#DEFINE AUDTRACE_HL +#DEFINE AUDTRACE_DE +#DEFINE AUDTRACE_IY + +#DEFINE AUDDEBUG(STR) + +#DEFINE AUDTRACE_CR +#ENDIF + + +#IFNDEF AUDIOUTILS +#DEFINE AUDIOUTILS + +AUD_NOTE: + AUDDEBUG("AUDNOTE ") + AUDTRACE_HL + AUDTRACE_CR + AUDTRACE_DE + AUDTRACE_CR + + push de + LD DE, 48 + CALL DIV16 + ; BC IS OCTAVE COUNT + ; HL is NOTE WITIN OCTAVE + ADD HL, HL + pop de + ADD HL, DE + + LD A, (HL) ; RETRIEVE PERIOD COUNT FROM SN7NOTETBL + INC HL + LD H, (HL) + LD L, A + + INC C +AUD_NOTE1: + DEC C + JR Z, AUD_NOTE2 + SRL H + RR L + JR AUD_NOTE1 + +AUD_NOTE2: + LD A, L ; IF NOT ZERO + OR H + RET NZ ; RETURN THE CALCULATED PERIOD + + LD H, $FF ; OTHERWISE RETURN -1 PERIOD (ERROR) + LD L, $FF + RET +#ENDIF diff --git a/Source/HBIOS/ay.asm b/Source/HBIOS/ay.asm deleted file mode 100644 index 85d9b9e2..00000000 --- a/Source/HBIOS/ay.asm +++ /dev/null @@ -1,122 +0,0 @@ -; -;====================================================================== -; PSG AY-3-8910 DRIVER FOR CONSOLE BELL -; WILL ALSO WORK WITH YM2149 -;====================================================================== -; -#IF (AYMODE == AYMODE_SCG) -AY_RSEL .EQU $9A -AY_RDAT .EQU $9B -AY_ACR .EQU $9C -#ENDIF -; -#IF (AYMODE == AYMODE_N8) -AY_RSEL .EQU $9C -AY_RDAT .EQU $9D -AY_ACR .EQU N8_DEFACR -#ENDIF -; -#IF (AYMODE == AYMODE_RCZ80) -AY_RSEL .EQU $D8 -AY_RDAT .EQU $D0 -#ENDIF -; -#IF (AYMODE == AYMODE_RCZ180) -AY_RSEL .EQU $68 -AY_RDAT .EQU $60 -#ENDIF -; -AY_R0CHAP .EQU $00 -AY_R1CHAP .EQU $01 -AY_R2CHBP .EQU $02 -AY_R3CHBP .EQU $03 -AY_R7ENAB .EQU $07 -AY_R8AVOL .EQU $08 -AY_R9BVOL .EQU $09 -; -;====================================================================== -; PSG AY-3-8910 DRIVER - INITIALIZATION -;====================================================================== -; -AY_INIT: - CALL NEWLINE ; FORMATTING - PRTS("AY: IO=0x$") - LD A,AY_RSEL - CALL PRTHEXBYTE - CALL AY_PROBE ; CHECK FOR HW EXISTENCE - JR Z,AY_INIT1 ; CONTINUE IF PRESENT -; -; HARDWARE NOT PRESENT -; - PRTS(" NOT PRESENT$") - OR $FF ; SIGNAL FAILURE - RET -; -AY_INIT1: - CALL AY_INIT2 - CALL AY_BEEP -AY_INIT2: - LD D,AY_R7ENAB ; SET MIXER CONTROL / IO ENABLE - LD E,$FF ; $FF - 11 111 111 - CALL AY_WRTPSG ; I/O PORTS DISABLED, NOISE CHANNEL C, B, A DISABLE, TONE CHANNEL C, B, A DISABLE -; - LD B,2 - LD D,AY_R8AVOL ; SET VOLUME TO 0 - LD E,$00 -AY_QUIET: - CALL AY_WRTPSG ; CYCLING THROUGH ALL CHANNELS - INC A - DJNZ AY_QUIET - RET -; -; PLAY A BEEP TONE ON CENTER CHANNEL (LEFT AND RIGHT SPEAKERS) -; -AY_BEEP: - LD D,AY_R2CHBP ; SET TONE PERIOD - LD E,$55 ; CHANNEL B - R00 & R01 - CALL AY_WRTPSG ; $0055 = XXXX0000 01010101 - LD D,AY_R3CHBP - LD E,0 - CALL AY_WRTPSG -; - LD D,AY_R7ENAB ; $FD = 11 111 101 - LD E,$FD ; SET MIXER CONTROL / IO ENABLE - CALL AY_WRTPSG ; I/O PORTS DISABLED, NOISE CHANNEL C, B, A DISABLE, TONE CHANNEL B ENABLE -; - LD D,AY_R9BVOL - LD E,$07 ; SET CHANNEL B VOLUME TO 50% (7/16) - CALL AY_WRTPSG -; - CALL LDELAY ; HALF SECOND - RET -; -; WRITE DATA E TO PSG REG A -; -AY_WRTPSG: - HB_DI -#IF (CPUFAM == CPU_Z180) - IN0 A,(Z180_DCNTL) ; GET WAIT STATES - PUSH AF ; SAVE VALUE - OR %00110000 ; FORCE SLOW OPERATION (I/O W/S=3) - OUT0 (Z180_DCNTL),A ; AND UPDATE DCNTL -#ENDIF - LD A,D - OUT (AY_RSEL),A - LD A,E - OUT (AY_RDAT),A -#IF (CPUFAM == CPU_Z180) - POP AF ; GET SAVED DCNTL VALUE - OUT0 (Z180_DCNTL),A ; AND RESTORE IT -#ENDIF - HB_EI - RET -; -; CHECK THERE IS A DEVICE PRESENT -; -AY_PROBE: -#IF ((AYMODE == AYMODE_SCG) | (AYMODE == AYMODE_N8)) - LD A,$FF - OUT (AY_ACR),A ; INIT AUX CONTROL REG -#ENDIF - XOR A - RET diff --git a/Source/HBIOS/ay38910.asm b/Source/HBIOS/ay38910.asm new file mode 100644 index 00000000..0eac02b2 --- /dev/null +++ b/Source/HBIOS/ay38910.asm @@ -0,0 +1,621 @@ +;====================================================================== +; +; AY-3-8910 / YM2149 SOUND DRIVER +; +;====================================================================== +; +; @3.579545 OCTAVE RANGE IS 2 - 7 (Bb2/A#2 .. A7) +; @4.000000 OCTAVE RANGE IS 2 - 7 (B2 .. A7) +; +AY_RCSND .EQU 0 ; 0 = EB MODULE, 1=MF MODULE +; +#IF (AYMODE == AYMODE_SCG) +AY_RSEL .EQU $9A +AY_RDAT .EQU $9B +AY_RIN .EQU AY_RSEL +AY_ACR .EQU $9C +AY_CLK .SET 3579545 ; MSX NTSC COLOUR BURST FREQ = 315/88 +#ENDIF +; +#IF (AYMODE == AYMODE_N8) +AY_RSEL .EQU $9C +AY_RDAT .EQU $9D +AY_RIN .EQU AY_RSEL +AY_ACR .EQU N8_DEFACR +#ENDIF +; +#IF (AYMODE == AYMODE_RCZ80) +AY_RSEL .EQU $D8 +AY_RDAT .EQU $D0 +AY_RIN .EQU AY_RSEL+AY_RCSND +#ENDIF +; +#IF (AYMODE == AYMODE_RCZ180) +AY_RSEL .EQU $68 +AY_RDAT .EQU $60 +AY_RIN .EQU AY_RSEL+AY_RCSND +#ENDIF +; +#IF (AYMODE == AYMODE_MSX) +AY_RSEL .EQU $A0 +AY_RDAT .EQU $A1 +AY_RIN .EQU $A2 +#ENDIF +; +;====================================================================== +; +; REGISTERS +; +AY_R2CHBP .EQU $02 +AY_R3CHBP .EQU $03 +AY_R7ENAB .EQU $07 +AY_R8AVOL .EQU $08 +; +;====================================================================== +; +; DRIVER FUNCTION TABLE AND INSTANCE DATA +; +AY_FNTBL: + .DW AY_RESET + .DW AY_VOLUME + .DW AY_PERIOD + .DW AY_NOTE + .DW AY_PLAY + .DW AY_QUERY + .DW AY_DURATION + .DW AY_DEVICE +; +#IF (($ - AY_FNTBL) != (SND_FNCNT * 2)) + .ECHO "*** INVALID SND FUNCTION TABLE ***\n" + !!!!! +#ENDIF +; +AY_IDAT .EQU 0 ; NO INSTANCE DATA ASSOCIATED WITH THIS DEVICE +; +;====================================================================== +; +; DEVICE CAPABILITIES AND CONFIGURATION +; +AY_TONECNT .EQU 3 ; COUNT NUMBER OF TONE CHANNELS +AY_NOISECNT .EQU 1 ; COUNT NUMBER OF NOISE CHANNELS +; +#IF (AY_CLK > 3579545) ; DEPENDING ON THE +AY_SCALE .EQU 2 ; INPUT CLOCK FREQUENCY +#ELSE ; PRESCALE THE TONE PERIOD +AY_SCALE .EQU 3 ; DATA TO MAINTAIN MAXIMUM +#ENDIF ; RANGE AND ACCURACY +; +AY_RATIO .EQU (AY_CLK * 100) / (16 >> AY_SCALE) +; +#INCLUDE "audio.inc" +; +;====================================================================== +; +; DRIVER INITIALIZATION (THERE IS NO PRE-INITIALIZATION) +; +; ANNOUNCE DEVICE ON CONSOLE. ACTIVATE DEVICE IF REQUIRED. +; SETUP FUNCTION TABLES. SETUP THE DEVICE. +; ANNOUNCE DEVICE WITH BEEP. SET VOLUME OFF. +; RETURN INITIALIZATION STATUS +; +AY38910_INIT: + CALL NEWLINE ; ANNOUNCE + PRTS("AY: IO=0x$") + LD A,AY_RSEL + CALL PRTHEXBYTE +; +#IF ((AYMODE == AYMODE_SCG) | (AYMODE == AYMODE_N8)) + LD A,$FF ; ACTIVATE DEVICE BIT 4 IS AY RESET CONTROL, BIT 3 IS ACTIVE LED + OUT (AY_ACR),A ; SET INIT AUX CONTROL REG +#ENDIF +; + LD DE,(AY_R2CHBP*256)+$55 ; SIMPLE HARDWARE PROBE + CALL AY_WRTPSG ; WRITE AND + CALL AY_RDPSG ; READ TO A + LD A,$55 ; SOUND CHANNEL + CP E ; REGISTER + JR Z,AY_FND +; + CALL PRTSTRD \ .TEXT " NOT PRESENT$" +; + LD A,$FF ; UNSUCCESSFULL INIT + RET +; +AY_FND: LD IY, AY_IDAT ; SETUP FUNCTION TABLE + LD BC, AY_FNTBL ; POINTER TO INSTANCE DATA + LD DE, AY_IDAT ; BC := FUNCTION TABLE ADDRESS + CALL SND_ADDENT ; DE := INSTANCE DATA PTR +; + CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION +; + LD E,$07 ; SET VOLUME TO 50% + CALL AY_SETV ; ON ALL CHANNELS +; +; LD DE,(AY_R2CHBP*256)+$55 ; BEEP ON CHANNEL B (CENTER) +; CALL AY_WRTPSG ; R02 = $55 = 01010101 + LD DE,(AY_R3CHBP*256)+$00 + CALL AY_WRTPSG ; R03 = $00 = XXXX0000 +; +#IF (SYSTIM != TM_NONE) + LD A, TICKFREQ / 3 ; SCHEDULE IN 1/3 SECOND TO TURN OFF SOUND + LD (AY_TIMTIK), A +; + LD HL, (VEC_TICK + 1) ; GET CUR TICKS VECTOR + LD (AY_TIMHOOK), HL ; SAVE IT INTERNALLY + LD HL, AY_TIMER ; INSTALL TIMER HOOK HANDLER + LD (VEC_TICK + 1), HL +; + LD A, $02 ; NOT READY & IN INTERUPT HANDLER + LD (AY_READY), A +#ELSE + CALL LDELAY ; HALF SECOND DELAY + LD E,$00 ; SET VOLUME OFF + CALL AY_SETV ; ON ALL CHANNELS + LD A, $01 ; READY & NOT IN INTERUPT HANDLER + LD (AY_READY), A +#ENDIF +; + XOR A ; SUCCESSFULL INIT + RET +; +#IF (SYSTIM != TM_NONE) +AY_TIMER: + LD A, (AY_TIMTIK) + DEC A + LD (AY_TIMTIK), A + JR NZ, AY_TIMER1 +; + LD E,$00 ; SET VOLUME OFF + CALL AY_SETV ; ON ALL CHANNELS + LD A, $01 ; READY & NOT IN INTERUPT HANDLER + LD (AY_READY), A +; + LD DE, AY_TIMER ; MAKE AY_TIMER A NO_OP HANDLER + LD HL, AY_TIMER1 + LD BC, 3 + LDIR +; +AY_TIMER1: + JP 0 ; OVERWRITTEN WITH NEXT HANDLER +AY_TIMHOOK: .EQU $ - 2 + +AY_TIMTIK .DB 0 ; COUNT DOWN TO FINISH BOOT BEEP +#ENDIF +; +;====================================================================== +; INITIALIZE DEVICE +;====================================================================== +; +AY_INIT: + LD DE,(AY_R7ENAB*256)+$F8 ; SET MIXER CONTROL / IO ENABLE. $F8 - 11 111 000 + JP AY_WRTPSG ; I/O PORTS = OUTPUT, NOISE CHANNEL C, B, A DISABLE, TONE CHANNEL C, B, A ENABLE +; +AY_CHKREDY: + LD A, (AY_READY) + BIT 0, A + RET NZ + + POP HL ; REMOVE LAST RETURN ADDRESS + OR $FF + RET ; RETURN NZ +; +;====================================================================== +; SET VOLUME ALL CHANNELS +;====================================================================== +; +AY_SETV: + PUSH BC + LD B,AY_TONECNT ; NUMBER OF CHANNELS + LD D,AY_R8AVOL ; BASE REGISTER FOR VOLUME +AY_SV: CALL AY_WRTPSG ; CYCLING THROUGH ALL CHANNELS + INC D + DJNZ AY_SV + POP BC + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - RESET +; +; INITIALIZE DEVICE. SET VOLUME OFF. RESET VOLUME AND TONE VARIABLES. +; +;====================================================================== +; +AY_RESET: + AUDTRACE(AYT_INIT) + CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY +; + PUSH DE + PUSH HL + CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION +; + AUDTRACE(AYT_VOLOFF) + LD E,0 ; SET VOLUME OFF + CALL AY_SETV ; ON ALL CHANNELS +; + XOR A ; SIGNAL SUCCESS + LD (AY_PENDING_VOLUME),A ; SET VOLUME TO ZERO + LD H,A + LD L,A + LD (AY_PENDING_PERIOD),HL ; SET TONE PERIOD TO ZERO +; + POP HL + POP DE + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - VOLUME +;====================================================================== +; +AY_VOLUME: + AUDTRACE(AYT_VOL) + AUDTRACE_L + AUDTRACE_CR + + LD A,L ; SAVE VOLUME + LD (AY_PENDING_VOLUME), A +; + XOR A ; SIGNAL SUCCESS + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - NOTE +;====================================================================== +; +AY_NOTE: + AUDTRACE(AYT_NOTE) + AUDTRACE_HL + AUDTRACE_CR +; +; CALL PRTHEXWORDHL +; CALL PC_COLON +; + LD DE, AY3NOTETBL ; ON ENTRY HL IS THE NOTE TO PLAY + PUSH DE ; AND DE IS THE START OF NOTE TABLE + LD DE, 48 ; LOAD DE WITH NOTE TABLE SIZE + CALL DIV16 ; AND CALCULATE OCTAVE COUNT IN BC +; + ADD HL, HL ; HL IS THE REMAINDER FROM ABOVE DIVISION (0-47) AND THE NOTE + POP DE ; TO PLAY IN THE OCTAVE. ADD IT TO THE START OF THE NOTE TABLE + ADD HL, DE ; TO POINT TO THE PERIOD FOR THE NOTE WE WANT TO PLAY. +; + LD A, (HL) ; HL POINT TO CURRENT PERIOD COUNT WE WANT TO PLAY + INC HL ; SO LOAD PERIOD COUNT FROM NOTE TABLE INTO HL + LD H, (HL) ; SO WE CAN UPDATE IT FOR THE REQUIRED OCTAVE + LD L, A +; + LD A,AY_SCALE-1 ; THE NOTE TABLE PERIOD DATA HAS BEEN + ADD A,C ; PRESCALED TO MAINTAIN RANGE SO ALLOW + LD B,A ; FOR THIS WHEN CHANGING OCTAVE +AY_NOTE1: + SRL H ; ADJUST THE PERIOD DATA + RR L ; FOR THE DESIRED OCTAVE + DJNZ AY_NOTE1 ; FALL THROUGH TO SET PERIOD AND RANGE CHECK +; +; CALL PRTHEXWORDHL +; CALL NEWLINE +; +;====================================================================== +; SOUND DRIVER FUNCTION - PERIOD +;====================================================================== +; +AY_PERIOD: + AUDTRACE(AYT_PERIOD) + AUDTRACE_HL + AUDTRACE_CR + + LD A, H ; IF ZERO - ERROR + OR L + JR Z, AY_PERIOD1 +; + LD A, H ; MAXIMUM TONE PERIOD IS 12-BITS + AND 11110000B ; ALLOWED RANGE IS 0001-0FFF (4095) + JR NZ, AY_PERIOD1 ; RETURN NZ IF NUMBER TOO LARGE + LD (AY_PENDING_PERIOD), HL ; SAVE AND RETURN SUCCESSFUL + RET +; +AY_PERIOD1: + LD A, $FF ; REQUESTED PERIOD IS LARGER + LD (AY_PENDING_PERIOD), A ; THAN THE DEVICE CAN SUPPORT + LD (AY_PENDING_PERIOD+1), A; SO SET PERIOD TO FFFF + RET ; AND RETURN FAILURE +; +;====================================================================== +; SOUND DRIVER FUNCTION - PLAY +; B = FUNCTION +; C = AUDIO DEVICE +; D = CHANNEL +; A = EXIT STATUS +;====================================================================== +; +AY_PLAY: + AUDTRACE(AYT_PLAY) + AUDTRACE_D + AUDTRACE_CR + CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY +; + LD A, (AY_PENDING_PERIOD + 1) ; CHECK THE HIGH BYTE OF THE PERIOD + INC A + JR Z, AY_PLAY1 ; PERIOD IS TOO LARGE, UNABLE TO PLAY +; + PUSH HL + PUSH DE + LD A,D ; LIMIT CHANNEL 0-2 + AND $3 ; AND INDEX TO THE + ADD A,A ; CHANNEL REGISTER + LD D,A ; FOR THE TONE PERIOD +; + AUDTRACE(AYT_REGWR) + AUDTRACE_A + AUDTRACE_CR +; + LD HL,AY_PENDING_PERIOD ; WRITE THE LOWER + ld E,(HL) ; 8-BITS OF THE TONE PERIOD + CALL AY_WRTPSG + INC D ; NEXT REGISTER + INC HL ; NEXT BYTE + LD E,(HL) ; WRITE THE UPPER + CALL AY_WRTPSG ; 8-BITS OF THE TONE PERIOD +; + POP DE ; RECALL CHANNEL + PUSH DE ; SAVE CHANNEL +; + LD A,D ; LIMIT CHANNEL 0-2 + AND $3 ; AND INDEX TO THE + ADD A,AY_R8AVOL ; CHANNEL VOLUME + LD D,A ; REGISTER +; + AUDTRACE(AYT_REGWR) + AUDTRACE_A + AUDTRACE_CR +; + INC HL ; NEXT BYTE + LD A,(HL) ; PENDING VOLUME + RRCA ; MAP THE VOLUME + RRCA ; FROM 00-FF + RRCA ; TO 00-0F + RRCA + AND $0F + LD E,A + CALL AY_WRTPSG ; SET VOL (E) IN CHANNEL REG (D) +; + POP DE ; RECALL CHANNEL + POP HL +; + XOR A ; SIGNAL SUCCESS + RET +; +AY_PLAY1: + PUSH DE ; TURN VOLUME OFF TO STOP PLAYING + LD A,D ; LIMIT CHANNEL 0-2 + AND $3 ; AND INDEX TO THE + ADD A,AY_R8AVOL ; CHANNEL VOLUME + LD D,A ; REGISTER + LD E,0 + CALL AY_WRTPSG ; SET VOL (E) IN CHANNEL REG (D) + POP DE + OR $FF ; SIGNAL FAILURE + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - QUERY AND SUBFUNCTIONS +;====================================================================== +; +AY_QUERY: + LD A, E + CP BF_SNDQ_CHCNT ; SUB FUNCTION 01 + JR Z, AY_QUERY_CHCNT +; + CP BF_SNDQ_VOLUME ; SUB FUNCTION 02 + JR Z, AY_QUERY_VOLUME +; + CP BF_SNDQ_PERIOD ; SUB FUNCTION 03 + JR Z, AY_QUERY_PERIOD +; + CP BF_SNDQ_DEV ; SUB FUNCTION 04 + JR Z, AY_QUERY_DEV +; + OR $FF ; SIGNAL FAILURE + RET +; +AY_QUERY_CHCNT: + LD BC,(AY_TONECNT*256)+AY_NOISECNT ; RETURN NUMBER OF + XOR A ; TONE AND NOISE + RET ; CHANNELS IN BC +; +AY_QUERY_PERIOD: + LD HL, (AY_PENDING_PERIOD) ; RETURN 16-BIT PERIOD + XOR A ; IN HL REGISTER + RET +; +AY_QUERY_VOLUME: + LD A, (AY_PENDING_VOLUME) ; RETURN 8-BIT VOLUME + LD L, A ; IN L REGISTER + XOR A +; LD H, A + RET +; +AY_QUERY_DEV: + LD B, SNDDEV_AY38910 ; RETURN DEVICE IDENTIFIER + LD DE, (AY_RSEL*256)+AY_RDAT ; AND ADDRESS AND DATA PORT + XOR A + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - DURATION +;====================================================================== +; +AY_DURATION: + LD (AY_PENDING_DURATION),HL ; SET TONE DURATION + XOR A + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - DEVICE +;====================================================================== +; +AY_DEVICE: + LD D,SNDDEV_AY38910 ; D := DEVICE TYPE + LD E,0 ; E := PHYSICAL UNIT + LD C,$00 ; C := DEVICE TYPE + LD H,AYMODE ; H := MODE + LD L,AY_RSEL ; L := BASE I/O ADDRESS + XOR A + RET +; +;====================================================================== +; NON-BLOCKING INTERRUPT CODE +;====================================================================== +; +AY_DI: + LD A, (AY_READY) + BIT 1, A + RET NZ + HB_DI + RET +; +AY_EI: + LD A, (AY_READY) + BIT 1, A + RET NZ + HB_EI + RET +; +;====================================================================== +; +; WRITE DATA IN E REGISTER TO DEVICE REGISTER D +; INTERRUPTS DISABLE DURING WRITE. WRITE IN SLOW MODE IF Z180 CPU. +; +;====================================================================== +; +AY_WRTPSG: + CALL AY_DI +#IFDEF SBCV2004 + LD A,8 ; SBC-V2-004 CHANGE + OUT (RTCIO),A ; TO HALF CLOCK SPEED +#ENDIF +#IF (CPUFAM == CPU_Z180) + IN0 A,(Z180_DCNTL) ; GET WAIT STATES + PUSH AF ; SAVE VALUE + OR %00110000 ; FORCE SLOW OPERATION (I/O W/S=3) + OUT0 (Z180_DCNTL),A ; AND UPDATE DCNTL +#ENDIF + LD A,D ; SELECT THE REGISTER WE + OUT (AY_RSEL),A ; WANT TO WRITE TO + LD A,E ; WRITE THE VALUE TO + OUT (AY_RDAT),A ; THE SELECTED REGISTER +#IF (CPUFAM == CPU_Z180) + POP AF ; GET SAVED DCNTL VALUE + OUT0 (Z180_DCNTL),A ; AND RESTORE IT +#ENDIF +#IFDEF SBCV2004 + LD A,0 ; SBC-V2-004 CHANGE TO + OUT (RTCIO),A ; NORMAL CLOCK SPEED +#ENDIF + JP AY_EI +; +;====================================================================== +; +; READ FROM REGISTER D AND RETURN WITH RESULT IN E +; +AY_RDPSG: + CALL AY_DI +#IFDEF SBCV2004 + LD A,8 ; SBC-V2-004 CHANGE + OUT (RTCIO),A ; TO HALF CLOCK SPEED +#ENDIF +#IF (CPUFAM == CPU_Z180) + IN0 A,(Z180_DCNTL) ; GET WAIT STATES + PUSH AF ; SAVE VALUE + OR %00110000 ; FORCE SLOW OPERATION (I/O W/S=3) + OUT0 (Z180_DCNTL),A ; AND UPDATE DCNTL +#ENDIF + LD A,D ; SELECT THE REGISTER WE + OUT (AY_RSEL),A ; WANT TO READ + IN A,(AY_RIN) ; READ SELECTED REGISTER + LD E,A +#IF (CPUFAM == CPU_Z180) + POP AF ; GET SAVED DCNTL VALUE + OUT0 (Z180_DCNTL),A ; AND RESTORE IT +#ENDIF +#IFDEF SBCV2004 + LD A,0 ; SBC-V2-004 CHANGE TO + OUT (RTCIO),A ; NORMAL CLOCK SPEED +#ENDIF + JP AY_EI +; +;====================================================================== +; +AY_PENDING_PERIOD .DW 0 ; PENDING PERIOD (12 BITS) ; ORDER +AY_PENDING_VOLUME .DB 0 ; PENDING VOL (8 BITS) ; SIGNIFICANT +AY_PENDING_DURATION .DW 0 ; PENDING DURATION (16 BITS) +AY_READY .DB 0 ; BIT 0 -> NZ DRIVER IS READY TO RECEIVE PLAY COMMAND + ; BIT 1 -> NZ EXECUTING WITHIN TIMER HANDLER = DO NOT DIS/ENABLE INT +; +#IF AUDIOTRACE +AYT_INIT .DB "\r\nAY_INIT\r\n$" +AYT_VOLOFF .DB "\r\nAY_VOLUME OFF\r\n$" +AYT_VOL .DB "\r\nAY_VOLUME: $" +AYT_NOTE .DB "\r\nAY_NOTE: $" +AYT_PERIOD .DB "\r\nAY_PERIOD $" +AYT_PLAY .DB "\r\nAY_PLAY CH: $" +AYT_REGWR .DB "\r\nOUT AY-3-8910 $" +#ENDIF +; +;====================================================================== +; QUARTER TONE FREQUENCY TABLE +;====================================================================== +; +; THE FREQUENCY BY QUARTER TONE STARTING AT A0# OCTAVE 0 +; USED TO MAP EACH OCTAVE (DIV BY 2 TO JUMP AN OCTAVE UP) +; FIRST PLAYABLE NOTE WILL BE 0 +; ASSUMING A CLOCK OF 1843200 THIS MAPS TO A0# +; +AY3NOTETBL: + .DW AY_RATIO / 2913 + .DW AY_RATIO / 2956 + .DW AY_RATIO / 2999 + .DW AY_RATIO / 3042 + .DW AY_RATIO / 3086 + .DW AY_RATIO / 3131 + .DW AY_RATIO / 3177 + .DW AY_RATIO / 3223 + .DW AY_RATIO / 3270 + .DW AY_RATIO / 3318 + .DW AY_RATIO / 3366 + .DW AY_RATIO / 3415 + .DW AY_RATIO / 3464 + .DW AY_RATIO / 3515 + .DW AY_RATIO / 3566 + .DW AY_RATIO / 3618 + .DW AY_RATIO / 3670 + .DW AY_RATIO / 3724 + .DW AY_RATIO / 3778 + .DW AY_RATIO / 3833 + .DW AY_RATIO / 3889 + .DW AY_RATIO / 3945 + .DW AY_RATIO / 4003 + .DW AY_RATIO / 4061 + .DW AY_RATIO / 4120 + .DW AY_RATIO / 4180 + .DW AY_RATIO / 4241 + .DW AY_RATIO / 4302 + .DW AY_RATIO / 4365 + .DW AY_RATIO / 4428 + .DW AY_RATIO / 4493 + .DW AY_RATIO / 4558 + .DW AY_RATIO / 4624 + .DW AY_RATIO / 4692 + .DW AY_RATIO / 4760 + .DW AY_RATIO / 4829 + .DW AY_RATIO / 4899 + .DW AY_RATIO / 4971 + .DW AY_RATIO / 5043 + .DW AY_RATIO / 5116 + .DW AY_RATIO / 5191 + .DW AY_RATIO / 5266 + .DW AY_RATIO / 5343 + .DW AY_RATIO / 5421 + .DW AY_RATIO / 5499 + .DW AY_RATIO / 5579 + .DW AY_RATIO / 5661 + .DW AY_RATIO / 5743 diff --git a/Source/HBIOS/bqrtc.asm b/Source/HBIOS/bqrtc.asm index 34854e22..5bb10ec4 100644 --- a/Source/HBIOS/bqrtc.asm +++ b/Source/HBIOS/bqrtc.asm @@ -159,6 +159,13 @@ BQRTC_DISPATCH: JP Z, BQRTC_GETALM ; Get Alarm DEC A JP Z, BQRTC_SETALM ; Set Alarm + DEC A + JP Z, BQRTC_DEVICE ; Report RTC device info + CALL SYSCHK + LD A,ERR_NOFUNC + OR A + RET + ; ; NVRAM FUNCTIONS ARE NOT AVAILABLE ; @@ -166,7 +173,10 @@ BQRTC_GETBYT: BQRTC_SETBYT: BQRTC_GETBLK: BQRTC_SETBLK: - CALL PANIC + CALL SYSCHK + LD A,ERR_NOTIMPL + OR A + RET ; RTC Get Time ; A: Result (OUT), 0=OK, Z=OK, NZ=Error @@ -328,6 +338,16 @@ BQRTC_SETALM: ; clean up and return XOR A ; Signal success RET ; And return +; +; REPORT RTC DEVICE INFO +; +BQRTC_DEVICE: + LD D,RTCDEV_BQ ; D := DEVICE TYPE + LD E,0 ; E := PHYSICAL DEVICE NUMBER + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,BQRTC_BASE ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET BQRTC_SUSPEND: IN0 A, (BQRTC_CONTROL) ; Suspend Clock diff --git a/Source/HBIOS/cfg_dyno.asm b/Source/HBIOS/cfg_dyno.asm index f44413f3..339cfce7 100644 --- a/Source/HBIOS/cfg_dyno.asm +++ b/Source/HBIOS/cfg_dyno.asm @@ -14,13 +14,14 @@ #DEFINE PLATFORM_NAME "DYNO" ; PLATFORM .EQU PLT_DYNO ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 18432000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 2 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 @@ -47,6 +48,8 @@ KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT ; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +; DIAGENABLE .EQU FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS DIAGDISKIO .EQU TRUE ; ENABLES DISK I/O ACTIVITY ON DIAGNOSTIC LEDS @@ -73,12 +76,17 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +; UARTENABLE .EQU FALSE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) ; ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) +ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) @@ -89,18 +97,16 @@ VDUENABLE .EQU FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_RCZ180 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_DYNO ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_DYNO ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -155,4 +161,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_RCZ180 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_ezz80.asm b/Source/HBIOS/cfg_ezz80.asm index 7b504f1d..2519e683 100644 --- a/Source/HBIOS/cfg_ezz80.asm +++ b/Source/HBIOS/cfg_ezz80.asm @@ -14,20 +14,21 @@ #DEFINE PLATFORM_NAME "EASYZ80" ; PLATFORM .EQU PLT_EZZ80 ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 10000000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 2 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_Z2 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +MEMMGR .EQU MM_Z2 ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER MPGSEL_0 .EQU $78 ; Z2 MEM MGR BANK 0 PAGE SELECT REG (WRITE ONLY) MPGSEL_1 .EQU $79 ; Z2 MEM MGR BANK 1 PAGE SELECT REG (WRITE ONLY) MPGSEL_2 .EQU $7A ; Z2 MEM MGR BANK 2 PAGE SELECT REG (WRITE ONLY) @@ -41,8 +42,16 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU TRUE ; ENABLE ZILOG CTC SUPPORT -CTCMODE .EQU CTCMODE_EZ ; CTC MODE: CTCMODE_[ZP|Z2|EZ|RC] +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT CTCBASE .EQU $88 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU TRUE ; ENABLE CTC PERIODIC TIMER +CTCMODE .EQU CTCMODE_CTR ; CTC MODE: CTCMODE_[NONE|CTR|TIM16|TIM256] +CTCPRE .EQU 256 ; PRESCALE CONSTANT (1-256) +CTCPRECH .EQU 2 ; PRESCALE CHANNEL (0-3) +CTCTIMCH .EQU 3 ; TIMER CHANNEL (0-3) +CTCOSC .EQU 921600 ; CTC CLOCK FREQUENCY +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS @@ -70,9 +79,18 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +DUARTCNT .EQU 2 ; DUART: NUMBER OF CHIPS TO DETECT (1-2) +DUART0BASE .EQU $A0 ; DUART 0: BASE ADDRESS OF CHIP +DUART0ACFG .EQU DEFSERCFG ; DUART 0A: SERIAL LINE CONFIG +DUART0BCFG .EQU DEFSERCFG ; DUART 0B: SERIAL LINE CONFIG +DUART1BASE .EQU $40 ; DUART 1: BASE ADDRESS OF CHIP +DUART1ACFG .EQU DEFSERCFG ; DUART 1A: SERIAL LINE CONFIG +DUART1BCFG .EQU DEFSERCFG ; DUART 1B: SERIAL LINE CONFIG +; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ -UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS +UARTCFG .EQU DEFSERCFG | SER_RTS ; UART: LINE CONFIG FOR UART PORTS UARTSBC .EQU FALSE ; UART: AUTO-DETECT SBC/ZETA ONBOARD UART UARTCAS .EQU FALSE ; UART: AUTO-DETECT ECB CASSETTE UART UARTMFP .EQU FALSE ; UART: AUTO-DETECT MF/PIC UART @@ -81,29 +99,29 @@ UARTRC .EQU TRUE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) SIODEBUG .EQU FALSE ; SIO: ENABLE DEBUG OUTPUT SIOCNT .EQU 2 ; SIO: NUMBER OF CHIPS TO DETECT (1-2), 2 CHANNELS PER CHIP -SIO0MODE .EQU SIOMODE_EZZ80 ; SIO 0: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO0CTCC .EQU -1 ; SIO 0: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0MODE .EQU SIOMODE_STD ; SIO 0: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO0BASE .EQU $80 ; SIO 0: REGISTERS BASE ADR SIO0ACLK .EQU 1843200 ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0ADIV .EQU 1 ; SIO 0A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0ACFG .EQU DEFSERCFG ; SIO 0A: SERIAL LINE CONFIG +SIO0ACTCC .EQU -1 ; SIO 0A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO0BCLK .EQU 1843200 ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0BDIV .EQU 1 ; SIO 0B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0BCFG .EQU DEFSERCFG ; SIO 0B: SERIAL LINE CONFIG -SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO1CTCC .EQU -1 ; SIO 1: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0BCTCC .EQU -1 ; SIO 0B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO1BASE .EQU $84 ; SIO 1: REGISTERS BASE ADR SIO1ACLK .EQU 7372800 ; SIO 1A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1ADIV .EQU 1 ; SIO 1A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1ACFG .EQU DEFSERCFG ; SIO 1A: SERIAL LINE CONFIG +SIO1ACTCC .EQU -1 ; SIO 1A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO1BCLK .EQU 7372800 ; SIO 1B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1BDIV .EQU 1 ; SIO 1B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1BCFG .EQU DEFSERCFG ; SIO 1B: SERIAL LINE CONFIG +SIO1BCTCC .EQU -1 ; SIO 1B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE ; XIOCFG .EQU DEFSERCFG ; XIO: SERIAL LINE CONFIG ; @@ -111,18 +129,16 @@ VDUENABLE .EQU FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -166,6 +182,9 @@ SDTRACE .EQU 1 ; SD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) SDCSIOFAST .EQU FALSE ; SD: ENABLE TABLE-DRIVEN BIT INVERTER IN CSIO MODE ; PRPENABLE .EQU FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) +PRPSDENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER SD CARD SUPPORT +PRPSDTRACE .EQU 1 ; PRP: SD CARD TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +PRPCONENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER VIDEO/KBD SUPPORT ; PPPENABLE .EQU FALSE ; PPP: ENABLE ZETA PARALLEL PORT PROPELLER BOARD DRIVER (PPP.ASM) ; @@ -177,4 +196,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm index 4632c77b..8aed93cf 100644 --- a/Source/HBIOS/cfg_master.asm +++ b/Source/HBIOS/cfg_master.asm @@ -11,20 +11,21 @@ #DEFINE PLATFORM_NAME "ROMWBW" ; PLATFORM .EQU PLT_SBC ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 8000000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 0 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_NONE ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +MEMMGR .EQU MM_NONE ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER RAMBIAS .EQU 0 ; OFFSET OF START OF RAM IN PHYSICAL ADDRESS SPACE MPCL_RAM .EQU $78 ; SBC MEM MGR RAM PAGE SELECT REG (WRITE ONLY) MPCL_ROM .EQU $7C ; SBC MEM MGR ROM PAGE SELECT REG (WRITE ONLY) @@ -39,6 +40,10 @@ Z180_CLKDIV .EQU 1 ; Z180: CHK DIV: 0=OSC/2, 1=OSC, 2=OSC*2 Z180_MEMWAIT .EQU 0 ; Z180: MEMORY WAIT STATES (0-3) Z180_IOWAIT .EQU 1 ; Z180: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3) ; +Z280_MEMWAIT .EQU 0 ; Z280: MEMORY WAIT STATES (0-3) +Z280_IOWAIT .EQU 1 ; Z280: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3) +Z280_INTWAIT .EQU 0 ; Z280: INT ACK WAIT STATUS (0-3) +; N8_PPI0 .EQU $80 ; N8: FIRST PARALLEL PORT REGISTERS BASE ADR N8_PPI1 .EQU $84 ; N8: SECOND PARALLEL PORT REGISTERS BASE ADR N8_RTC .EQU $88 ; N8: RTC LATCH REGISTER ADR @@ -59,8 +64,16 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT -CTCMODE .EQU CTCMODE_ZP ; CTC MODE: CTCMODE_[ZP|Z2|EZ|RC] -CTCBASE .EQU $20 ; CTC BASE I/O ADDRESS +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT +CTCBASE .EQU $B0 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU FALSE ; ENABLE CTC PERIODIC TIMER +CTCMODE .EQU CTCMODE_CTR ; CTC MODE: CTCMODE_[NONE|CTR|TIM16|TIM256] +CTCPRE .EQU 256 ; PRESCALE CONSTANT (1-256) +CTCPRECH .EQU 2 ; PRESCALE CHANNEL (0-3) +CTCTIMCH .EQU 3 ; TIMER CHANNEL (0-3) +CTCOSC .EQU 614400 ; CTC CLOCK FREQUENCY +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS @@ -92,6 +105,15 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +DUARTCNT .EQU 2 ; DUART: NUMBER OF CHIPS TO DETECT (1-2) +DUART0BASE .EQU $A0 ; DUART 0: BASE ADDRESS OF CHIP +DUART0ACFG .EQU DEFSERCFG ; DUART 0A: SERIAL LINE CONFIG +DUART0BCFG .EQU DEFSERCFG ; DUART 0B: SERIAL LINE CONFIG +DUART1BASE .EQU $40 ; DUART 1: BASE ADDRESS OF CHIP +DUART1ACFG .EQU DEFSERCFG ; DUART 1A: SERIAL LINE CONFIG +DUART1BCFG .EQU DEFSERCFG ; DUART 1B: SERIAL LINE CONFIG +; UARTENABLE .EQU FALSE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS @@ -103,9 +125,16 @@ UART4 .EQU FALSE ; UART: AUTO-DETECT 4UART UART UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) +ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +Z2UOSC .EQU 1843200 ; Z2U: OSC FREQUENCY IN MHZ +Z2UOSCEXT .EQU TRUE ; Z2U: USE EXTERNAL OSCILLATOR +Z2U0BASE .EQU $10 ; Z2U 0: BASE I/O ADDRESS +Z2U0CFG .EQU DEFSERCFG ; Z2U 0: SERIAL LINE CONFIG +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ACIADEBUG .EQU FALSE ; ACIA: ENABLE DEBUG OUTPUT ACIACNT .EQU 1 ; ACIA: NUMBER OF CHIPS TO DETECT (1-2) @@ -121,24 +150,22 @@ ACIA1CFG .EQU DEFSERCFG ; ACIA 1: SERIAL LINE CONFIG (SEE STD.ASM) SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) SIODEBUG .EQU FALSE ; SIO: ENABLE DEBUG OUTPUT SIOCNT .EQU 2 ; SIO: NUMBER OF CHIPS TO DETECT (1-2), 2 CHANNELS PER CHIP -SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO0CTCC .EQU -1 ; SIO 0: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO0BASE .EQU $80 ; SIO 0: REGISTERS BASE ADR SIO0ACLK .EQU CPUOSC ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0ADIV .EQU 1 ; SIO 0A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0ACFG .EQU DEFSERCFG ; SIO 0A: SERIAL LINE CONFIG +SIO0ACTCC .EQU -1 ; SIO 0A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO0BCLK .EQU CPUOSC ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0BDIV .EQU 1 ; SIO 0B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0BCFG .EQU DEFSERCFG ; SIO 0B: SERIAL LINE CONFIG -SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO1CTCC .EQU -1 ; SIO 1: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0BCTCC .EQU -1 ; SIO 0B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO1BASE .EQU $84 ; SIO 1: REGISTERS BASE ADR SIO1ACLK .EQU CPUOSC ; SIO 1A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1ADIV .EQU 1 ; SIO 1A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1ACFG .EQU DEFSERCFG ; SIO 1A: SERIAL LINE CONFIG +SIO1ACTCC .EQU -1 ; SIO 1A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO1BCLK .EQU CPUOSC ; SIO 1B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1BDIV .EQU 1 ; SIO 1B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1BCFG .EQU DEFSERCFG ; SIO 1B: SERIAL LINE CONFIG +SIO1BCTCC .EQU -1 ; SIO 1B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE ; XIOCFG .EQU DEFSERCFG ; XIO: SERIAL LINE CONFIG ; @@ -148,19 +175,17 @@ CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) TMSMODE .EQU TMSMODE_NONE ; TMS: DRIVER MODE: TMSMODE_[SCG/N8] +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) VGASIZ .EQU V80X25 ; VGA: DISPLAY FORMAT [V80X25|V80X30|V80X43] ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_NONE ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_NONE ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_NONE ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -232,4 +257,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) UFBASE .EQU $0C ; UF: REGISTERS BASE ADR ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_NONE ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index 69645f3e..6bda2c1c 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -14,20 +14,21 @@ #DEFINE PLATFORM_NAME "MARK IV" ; PLATFORM .EQU PLT_MK4 ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 18432000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 2 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_Z180 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +MEMMGR .EQU MM_Z180 ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER RAMBIAS .EQU 512 ; OFFSET OF START OF RAM IN PHYSICAL ADDRESS SPACE ; Z180_BASE .EQU $40 ; Z180: I/O BASE ADDRESS FOR INTERNAL REGISTERS @@ -46,6 +47,11 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT +CTCBASE .EQU $B0 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU FALSE ; ENABLE CTC PERIODIC TIMER +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS @@ -77,6 +83,8 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS @@ -88,9 +96,12 @@ UART4 .EQU TRUE ; UART: AUTO-DETECT 4UART UART UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) +ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) @@ -103,19 +114,17 @@ CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) TMSMODE .EQU TMSMODE_SCG ; TMS: DRIVER MODE: TMSMODE_[SCG/N8] +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) VGASIZ .EQU V80X25 ; VGA: DISPLAY FORMAT [V80X25|V80X30|V80X43] ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_SCG ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_N8 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_DIDE ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -186,4 +195,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) UFBASE .EQU $0C ; UF: REGISTERS BASE ADR ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_SCG ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index 0ef5b66a..d26166c4 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -14,20 +14,21 @@ #DEFINE PLATFORM_NAME "N8" ; PLATFORM .EQU PLT_N8 ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 18432000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 2 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_N8 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +MEMMGR .EQU MM_N8 ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER RAMBIAS .EQU 0 ; OFFSET OF START OF RAM IN PHYSICAL ADDRESS SPACE ; Z180_BASE .EQU $40 ; Z180: I/O BASE ADDRESS FOR INTERNAL REGISTERS @@ -49,6 +50,11 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT +CTCBASE .EQU $B0 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU FALSE ; ENABLE CTC PERIODIC TIMER +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS @@ -80,6 +86,8 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS @@ -91,9 +99,12 @@ UART4 .EQU TRUE ; UART: AUTO-DETECT 4UART UART UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) +ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) @@ -106,19 +117,17 @@ CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU TRUE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) TMSMODE .EQU TMSMODE_N8 ; TMS: DRIVER MODE: TMSMODE_[SCG/N8] +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) VGASIZ .EQU V80X25 ; VGA: DISPLAY FORMAT [V80X25|V80X30|V80X43] ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU TRUE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_N8 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU TRUE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_N8 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_N8 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -186,4 +195,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) FIFO_BASE .EQU $0C ; UF: REGISTERS BASE ADR ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU TRUE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_N8 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_rcz180.asm b/Source/HBIOS/cfg_rcz180.asm index 95a61af9..fd013bb3 100644 --- a/Source/HBIOS/cfg_rcz180.asm +++ b/Source/HBIOS/cfg_rcz180.asm @@ -1,6 +1,6 @@ ; ;================================================================================================== -; ROMWBW 2.X CONFIGURATION DEFAULTS FOR RC2014 +; ROMWBW 2.X CONFIGURATION DEFAULTS FOR RC2014 Z180 CPU ;================================================================================================== ; ; THIS FILE CONTAINS THE FULL SET OF DEFAULT CONFIGURATION SETTINGS FOR THE PLATFORM @@ -14,20 +14,21 @@ #DEFINE PLATFORM_NAME "RC2014" ; PLATFORM .EQU PLT_RCZ180 ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 18432000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 2 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_Z180 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +MEMMGR .EQU MM_Z180 ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER RAMBIAS .EQU 512 ; OFFSET OF START OF RAM IN PHYSICAL ADDRESS SPACE MPGSEL_0 .EQU $78 ; Z2 MEM MGR BANK 0 PAGE SELECT REG (WRITE ONLY) MPGSEL_1 .EQU $79 ; Z2 MEM MGR BANK 1 PAGE SELECT REG (WRITE ONLY) @@ -46,6 +47,11 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT +CTCBASE .EQU $88 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU FALSE ; ENABLE CTC PERIODIC TIMER +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS @@ -73,9 +79,18 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +DUARTCNT .EQU 2 ; DUART: NUMBER OF CHIPS TO DETECT (1-2) +DUART0BASE .EQU $A0 ; DUART 0: BASE ADDRESS OF CHIP +DUART0ACFG .EQU DEFSERCFG ; DUART 0A: SERIAL LINE CONFIG +DUART0BCFG .EQU DEFSERCFG ; DUART 0B: SERIAL LINE CONFIG +DUART1BASE .EQU $40 ; DUART 1: BASE ADDRESS OF CHIP +DUART1ACFG .EQU DEFSERCFG ; DUART 1A: SERIAL LINE CONFIG +DUART1BCFG .EQU DEFSERCFG ; DUART 1B: SERIAL LINE CONFIG +; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ -UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS +UARTCFG .EQU DEFSERCFG | SER_RTS ; UART: LINE CONFIG FOR UART PORTS UARTSBC .EQU FALSE ; UART: AUTO-DETECT SBC/ZETA ONBOARD UART UARTCAS .EQU FALSE ; UART: AUTO-DETECT ECB CASSETTE UART UARTMFP .EQU FALSE ; UART: AUTO-DETECT MF/PIC UART @@ -83,32 +98,33 @@ UART4 .EQU FALSE ; UART: AUTO-DETECT 4UART UART UARTRC .EQU TRUE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) +ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) SIODEBUG .EQU FALSE ; SIO: ENABLE DEBUG OUTPUT SIOCNT .EQU 2 ; SIO: NUMBER OF CHIPS TO DETECT (1-2), 2 CHANNELS PER CHIP -SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO0CTCC .EQU -1 ; SIO 0: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO0BASE .EQU $80 ; SIO 0: REGISTERS BASE ADR SIO0ACLK .EQU 7372800 ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0ADIV .EQU 1 ; SIO 0A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) -SIO0ACFG .EQU SER_115200_8N1 ; SER_115200_8N1 0A: SERIAL LINE CONFIG +SIO0ACFG .EQU SER_115200_8N1 ; SIO 0A: SERIAL LINE CONFIG +SIO0ACTCC .EQU -1 ; SIO 0A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO0BCLK .EQU 7372800 ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0BDIV .EQU 1 ; SIO 0B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0BCFG .EQU SER_115200_8N1 ; SIO 0B: SERIAL LINE CONFIG -SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO1CTCC .EQU -1 ; SIO 1: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0BCTCC .EQU -1 ; SIO 0B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO1BASE .EQU $84 ; SIO 1: REGISTERS BASE ADR SIO1ACLK .EQU 7372800 ; SIO 1A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1ADIV .EQU 1 ; SIO 1A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) -SIO1ACFG .EQU SER_115200_8N1 ; SER_115200_8N1 1A: SERIAL LINE CONFIG +SIO1ACFG .EQU SER_115200_8N1 ; SIO 1A: SERIAL LINE CONFIG +SIO1ACTCC .EQU -1 ; SIO 1A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO1BCLK .EQU 7372800 ; SIO 1B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1BDIV .EQU 1 ; SIO 1B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1BCFG .EQU SER_115200_8N1 ; SIO 1B: SERIAL LINE CONFIG +SIO1BCTCC .EQU -1 ; SIO 1B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE ; XIOCFG .EQU DEFSERCFG ; XIO: SERIAL LINE CONFIG ; @@ -116,18 +132,17 @@ VDUENABLE .EQU FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSMODE .EQU TMSMODE_RC ; TMS: DRIVER MODE: TMSMODE_[SCG/N8] +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_RCZ180 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -168,14 +183,18 @@ PPIDE1A8BIT .EQU FALSE ; PPIDE 1A (MASTER): 8 BIT XFER PPIDE1B8BIT .EQU FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER PPIDE2BASE .EQU $00 ; PPIDE 2: PPI REGISTERS BASE ADR PPIDE2A8BIT .EQU FALSE ; PPIDE 2A (MASTER): 8 BIT XFER -PPIDE2B8BIT .EQU FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER; +PPIDE2B8BIT .EQU FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER +; SDENABLE .EQU FALSE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) -SDMODE .EQU SDMODE_PPI ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4|SC|MT] +SDMODE .EQU SDMODE_MT ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4|SC|MT] SDCNT .EQU 1 ; SD: NUMBER OF SD CARD DEVICES (1-2), FOR DSD & SC ONLY SDTRACE .EQU 1 ; SD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) SDCSIOFAST .EQU FALSE ; SD: ENABLE TABLE-DRIVEN BIT INVERTER IN CSIO MODE ; PRPENABLE .EQU FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) +PRPSDENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER SD CARD SUPPORT +PRPSDTRACE .EQU 1 ; PRP: SD CARD TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +PRPCONENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER VIDEO/KBD SUPPORT ; PPPENABLE .EQU FALSE ; PPP: ENABLE ZETA PARALLEL PORT PROPELLER BOARD DRIVER (PPP.ASM) ; @@ -187,4 +206,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_RCZ180 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_rcz280.asm b/Source/HBIOS/cfg_rcz280.asm new file mode 100644 index 00000000..2dfefba7 --- /dev/null +++ b/Source/HBIOS/cfg_rcz280.asm @@ -0,0 +1,230 @@ +; +;================================================================================================== +; ROMWBW 2.X CONFIGURATION DEFAULTS FOR RC2014 Z280 CPU +;================================================================================================== +; +; THIS FILE CONTAINS THE FULL SET OF DEFAULT CONFIGURATION SETTINGS FOR THE PLATFORM +; INDICATED ABOVE. THIS FILE SHOULD *NOT* NORMALLY BE CHANGED. INSTEAD, YOU SHOULD +; OVERRIDE ANY SETTINGS YOU WANT USING A CONFIGURATION FILE IN THE CONFIG DIRECTORY +; UNDER THIS DIRECTORY. +; +; THIS FILE CAN BE CONSIDERED A REFERENCE THAT LISTS ALL POSSIBLE CONFIGURATION SETTINGS +; FOR THE PLATFORM. +; +#DEFINE PLATFORM_NAME "RC2014" +; +PLATFORM .EQU PLT_RCZ80 ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] +CPUFAM .EQU CPU_Z280 ; CPU FAMILY: CPU_[Z80|Z180|Z280] +BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] +BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE +HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) +USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) +; +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE +; +CPUOSC .EQU 24000000 ; CPU OSC FREQ IN MHZ +INTMODE .EQU 0 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 +DEFSERCFG .EQU SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) +; +RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) +MEMMGR .EQU MM_Z2 ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER +MPGSEL_0 .EQU $78 ; Z2 MEM MGR BANK 0 PAGE SELECT REG (WRITE ONLY) +MPGSEL_1 .EQU $79 ; Z2 MEM MGR BANK 1 PAGE SELECT REG (WRITE ONLY) +MPGSEL_2 .EQU $7A ; Z2 MEM MGR BANK 2 PAGE SELECT REG (WRITE ONLY) +MPGSEL_3 .EQU $7B ; Z2 MEM MGR BANK 3 PAGE SELECT REG (WRITE ONLY) +MPGENA .EQU $7C ; Z2 MEM MGR PAGING ENABLE REGISTER (BIT 0, WRITE ONLY) +; +Z280_MEMWAIT .EQU 0 ; Z280: MEMORY WAIT STATES (0-3) +Z280_IOWAIT .EQU 1 ; Z280: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3) +Z280_INTWAIT .EQU 0 ; Z280: INT ACK WAIT STATUS (0-3) +; +RTCIO .EQU $C0 ; RTC LATCH REGISTER ADR +; +KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT +KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS +; +CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT +CTCBASE .EQU $88 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU FALSE ; ENABLE CTC PERIODIC TIMER +CTCMODE .EQU CTCMODE_TIM16 ; CTC MODE: CTCMODE_[NONE|CTR|TIM16|TIM256] +CTCPRE .EQU 256 ; PRESCALE CONSTANT (1-256) +CTCPRECH .EQU 2 ; PRESCALE CHANNEL (0-3) +CTCTIMCH .EQU 3 ; TIMER CHANNEL (0-3) +CTCOSC .EQU 7372800 ; CTC CLOCK FREQUENCY +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +; +DIAGENABLE .EQU TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT +DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS +DIAGDISKIO .EQU TRUE ; ENABLES DISK I/O ACTIVITY ON DIAGNOSTIC LEDS +; +LEDENABLE .EQU FALSE ; ENABLES STATUS LED (SINGLE LED) +LEDPORT .EQU $0E ; STATUS LED PORT ADDRESS +LEDDISKIO .EQU TRUE ; ENABLES DISK I/O ACTIVITY ON STATUS LED +; +DSKYENABLE .EQU FALSE ; ENABLES DSKY (DO NOT COMBINE WITH PPIDE) +; +CRTACT .EQU FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP +VDAEMU .EQU EMUTYP_ANSI ; VDA EMULATION: EMUTYP_[TTY|ANSI] +ANSITRACE .EQU 1 ; ANSI DRIVER TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +; +DSRTCENABLE .EQU TRUE ; DSRTC: ENABLE DS-1302 CLOCK DRIVER (DSRTC.ASM) +DSRTCMODE .EQU DSRTCMODE_STD ; DSRTC: OPERATING MODE: DSRTC_[STD|MFPIC] +DSRTCCHG .EQU FALSE ; DSRTC: FORCE BATTERY CHARGE ON (USE WITH CAUTION!!!) +; +BQRTCENABLE .EQU FALSE ; BQRTC: ENABLE BQ4845 CLOCK DRIVER (BQRTC.ASM) +BQRTC_BASE .EQU $50 ; BQRTC: I/O BASE ADDRESS +; +INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) +; +HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT +SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) +; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +DUARTCNT .EQU 2 ; DUART: NUMBER OF CHIPS TO DETECT (1-2) +DUART0BASE .EQU $A0 ; DUART 0: BASE ADDRESS OF CHIP +DUART0ACFG .EQU DEFSERCFG ; DUART 0A: SERIAL LINE CONFIG +DUART0BCFG .EQU DEFSERCFG ; DUART 0B: SERIAL LINE CONFIG +DUART1BASE .EQU $40 ; DUART 1: BASE ADDRESS OF CHIP +DUART1ACFG .EQU DEFSERCFG ; DUART 1A: SERIAL LINE CONFIG +DUART1BCFG .EQU DEFSERCFG ; DUART 1B: SERIAL LINE CONFIG +; +UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) +UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ +UARTCFG .EQU DEFSERCFG | SER_RTS ; UART: LINE CONFIG FOR UART PORTS +UARTSBC .EQU FALSE ; UART: AUTO-DETECT SBC/ZETA ONBOARD UART +UARTCAS .EQU FALSE ; UART: AUTO-DETECT ECB CASSETTE UART +UARTMFP .EQU FALSE ; UART: AUTO-DETECT MF/PIC UART +UART4 .EQU FALSE ; UART: AUTO-DETECT 4UART UART +UARTRC .EQU TRUE ; UART: AUTO-DETECT RC UART +; +ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) +; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +Z2UOSC .EQU 1843200 ; Z2U: OSC FREQUENCY IN MHZ +Z2UOSCEXT .EQU TRUE ; Z2U: USE EXTERNAL OSCILLATOR +Z2U0BASE .EQU $10 ; Z2U 0: BASE I/O ADDRESS +Z2U0CFG .EQU DEFSERCFG ; Z2U 0: SERIAL LINE CONFIG +; +ACIAENABLE .EQU TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) +ACIADEBUG .EQU FALSE ; ACIA: ENABLE DEBUG OUTPUT +ACIACNT .EQU 1 ; ACIA: NUMBER OF CHIPS TO DETECT (1-2) +ACIA0BASE .EQU $80 ; ACIA 0: REGISTERS BASE ADR +ACIA0CLK .EQU 7372800 ; ACIA 0: OSC FREQ IN HZ +ACIA0DIV .EQU 1 ; ACIA 0: SERIAL CLOCK DIVIDER +ACIA0CFG .EQU DEFSERCFG ; ACIA 0: SERIAL LINE CONFIG (SEE STD.ASM) +ACIA1BASE .EQU $40 ; ACIA 1: REGISTERS BASE ADR +ACIA1CLK .EQU 7372800 ; ACIA 1: OSC FREQ IN HZ +ACIA1DIV .EQU 1 ; ACIA 1: SERIAL CLOCK DIVIDER +ACIA1CFG .EQU DEFSERCFG ; ACIA 1: SERIAL LINE CONFIG (SEE STD.ASM) +; +SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) +SIODEBUG .EQU FALSE ; SIO: ENABLE DEBUG OUTPUT +SIOCNT .EQU 2 ; SIO: NUMBER OF CHIPS TO DETECT (1-2), 2 CHANNELS PER CHIP +SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] +SIO0BASE .EQU $80 ; SIO 0: REGISTERS BASE ADR +SIO0ACLK .EQU 7372800 ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 +SIO0ACFG .EQU DEFSERCFG ; SIO 0A: SERIAL LINE CONFIG +SIO0ACTCC .EQU -1 ; SIO 0A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO0BCLK .EQU 7372800 ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 +SIO0BCFG .EQU DEFSERCFG ; SIO 0B: SERIAL LINE CONFIG +SIO0BCTCC .EQU -1 ; SIO 0B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] +SIO1BASE .EQU $84 ; SIO 1: REGISTERS BASE ADR +SIO1ACLK .EQU 7372800 ; SIO 1A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 +SIO1ACFG .EQU DEFSERCFG ; SIO 1A: SERIAL LINE CONFIG +SIO1ACTCC .EQU -1 ; SIO 1A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO1BCLK .EQU 7372800 ; SIO 1B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 +SIO1BCFG .EQU DEFSERCFG ; SIO 1B: SERIAL LINE CONFIG +SIO1BCTCC .EQU -1 ; SIO 1B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +; +XIOCFG .EQU DEFSERCFG ; XIO: SERIAL LINE CONFIG +; +VDUENABLE .EQU FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) +CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) +NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) +TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSMODE .EQU TMSMODE_RC ; TMS: DRIVER MODE: TMSMODE_[SCG/N8] +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) +VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) +; +MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) +MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM +; +FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) +FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) +FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) +FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] +FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] +FDMAUTO .EQU TRUE ; FD: AUTO SELECT DEFAULT/ALTERNATE MEDIA FORMATS +; +RFENABLE .EQU FALSE ; RF: ENABLE RAM FLOPPY DRIVER +; +IDEENABLE .EQU FALSE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) +IDETRACE .EQU 1 ; IDE: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +IDECNT .EQU 1 ; IDE: NUMBER OF IDE INTERFACES TO DETECT (1-3), 2 DRIVES EACH +IDE0MODE .EQU IDEMODE_RC ; IDE 0: DRIVER MODE: IDEMODE_[DIO|DIDE|MK4|RC] +IDE0BASE .EQU $10 ; IDE 0: IO BASE ADDRESS +IDE0DATLO .EQU $00 ; IDE 0: DATA LO PORT FOR 16-BIT I/O +IDE0DATHI .EQU $00 ; IDE 0: DATA HI PORT FOR 16-BIT I/O +IDE0A8BIT .EQU TRUE ; IDE 0A (MASTER): 8 BIT XFER +IDE0B8BIT .EQU TRUE ; IDE 0B (MASTER): 8 BIT XFER +IDE1MODE .EQU IDEMODE_NONE ; IDE 1: DRIVER MODE: IDEMODE_[DIO|DIDE|MK4|RC] +IDE1BASE .EQU $00 ; IDE 1: IO BASE ADDRESS +IDE1DATLO .EQU $00 ; IDE 1: DATA LO PORT FOR 16-BIT I/O +IDE1DATHI .EQU $00 ; IDE 1: DATA HI PORT FOR 16-BIT I/O +IDE1A8BIT .EQU TRUE ; IDE 1A (MASTER): 8 BIT XFER +IDE1B8BIT .EQU TRUE ; IDE 1B (MASTER): 8 BIT XFER +IDE2MODE .EQU IDEMODE_NONE ; IDE 2: DRIVER MODE: IDEMODE_[DIO|DIDE|MK4|RC] +IDE2BASE .EQU $00 ; IDE 2: IO BASE ADDRESS +IDE2DATLO .EQU $00 ; IDE 2: DATA LO PORT FOR 16-BIT I/O +IDE2DATHI .EQU $00 ; IDE 2: DATA HI PORT FOR 16-BIT I/O +IDE2A8BIT .EQU TRUE ; IDE 2A (MASTER): 8 BIT XFER +IDE2B8BIT .EQU TRUE ; IDE 2B (MASTER): 8 BIT XFER +; +PPIDEENABLE .EQU FALSE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +PPIDETRACE .EQU 1 ; PPIDE: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +PPIDECNT .EQU 1 ; PPIDE: NUMBER OF PPI CHIPS TO DETECT (1-3), 2 DRIVES PER CHIP +PPIDE0BASE .EQU $20 ; PPIDE 0: PPI REGISTERS BASE ADR +PPIDE0A8BIT .EQU FALSE ; PPIDE 0A (MASTER): 8 BIT XFER +PPIDE0B8BIT .EQU FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER +PPIDE1BASE .EQU $00 ; PPIDE 1: PPI REGISTERS BASE ADR +PPIDE1A8BIT .EQU FALSE ; PPIDE 1A (MASTER): 8 BIT XFER +PPIDE1B8BIT .EQU FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER +PPIDE2BASE .EQU $00 ; PPIDE 2: PPI REGISTERS BASE ADR +PPIDE2A8BIT .EQU FALSE ; PPIDE 2A (MASTER): 8 BIT XFER +PPIDE2B8BIT .EQU FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER +; +SDENABLE .EQU FALSE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) +SDMODE .EQU SDMODE_MT ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4|SC|MT] +SDCNT .EQU 1 ; SD: NUMBER OF SD CARD DEVICES (1-2), FOR DSD & SC ONLY +SDTRACE .EQU 1 ; SD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +SDCSIOFAST .EQU FALSE ; SD: ENABLE TABLE-DRIVEN BIT INVERTER IN CSIO MODE +; +PRPENABLE .EQU FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) +PRPSDENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER SD CARD SUPPORT +PRPSDTRACE .EQU 1 ; PRP: SD CARD TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +PRPCONENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER VIDEO/KBD SUPPORT +; +PPPENABLE .EQU FALSE ; PPP: ENABLE ZETA PARALLEL PORT PROPELLER BOARD DRIVER (PPP.ASM) +; +HDSKENABLE .EQU FALSE ; HDSK: ENABLE SIMH HDSK DISK DRIVER (HDSK.ASM) +; +PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD +PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) +PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP +; +UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) +; +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU 7372800 / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU 7372800 / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_rcz80.asm b/Source/HBIOS/cfg_rcz80.asm index a737da64..af0c027d 100644 --- a/Source/HBIOS/cfg_rcz80.asm +++ b/Source/HBIOS/cfg_rcz80.asm @@ -14,20 +14,21 @@ #DEFINE PLATFORM_NAME "RC2014" ; PLATFORM .EQU PLT_RCZ80 ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 7372800 ; CPU OSC FREQ IN MHZ INTMODE .EQU 1 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_Z2 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +MEMMGR .EQU MM_Z2 ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER MPGSEL_0 .EQU $78 ; Z2 MEM MGR BANK 0 PAGE SELECT REG (WRITE ONLY) MPGSEL_1 .EQU $79 ; Z2 MEM MGR BANK 1 PAGE SELECT REG (WRITE ONLY) MPGSEL_2 .EQU $7A ; Z2 MEM MGR BANK 2 PAGE SELECT REG (WRITE ONLY) @@ -40,8 +41,16 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT -CTCMODE .EQU CTCMODE_RC ; CTC MODE: CTCMODE_[ZP|Z2|EZ|RC] +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT CTCBASE .EQU $88 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU FALSE ; ENABLE CTC PERIODIC TIMER +CTCMODE .EQU CTCMODE_TIM16 ; CTC MODE: CTCMODE_[NONE|CTR|TIM16|TIM256] +CTCPRE .EQU 256 ; PRESCALE CONSTANT (1-256) +CTCPRECH .EQU 2 ; PRESCALE CHANNEL (0-3) +CTCTIMCH .EQU 3 ; TIMER CHANNEL (0-3) +CTCOSC .EQU CPUOSC ; CTC CLOCK FREQUENCY +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS @@ -69,9 +78,18 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +DUARTCNT .EQU 2 ; DUART: NUMBER OF CHIPS TO DETECT (1-2) +DUART0BASE .EQU $A0 ; DUART 0: BASE ADDRESS OF CHIP +DUART0ACFG .EQU DEFSERCFG ; DUART 0A: SERIAL LINE CONFIG +DUART0BCFG .EQU DEFSERCFG ; DUART 0B: SERIAL LINE CONFIG +DUART1BASE .EQU $40 ; DUART 1: BASE ADDRESS OF CHIP +DUART1ACFG .EQU DEFSERCFG ; DUART 1A: SERIAL LINE CONFIG +DUART1BCFG .EQU DEFSERCFG ; DUART 1B: SERIAL LINE CONFIG +; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ -UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS +UARTCFG .EQU DEFSERCFG | SER_RTS ; UART: LINE CONFIG FOR UART PORTS UARTSBC .EQU FALSE ; UART: AUTO-DETECT SBC/ZETA ONBOARD UART UARTCAS .EQU FALSE ; UART: AUTO-DETECT ECB CASSETTE UART UARTMFP .EQU FALSE ; UART: AUTO-DETECT MF/PIC UART @@ -80,6 +98,8 @@ UARTRC .EQU TRUE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ACIADEBUG .EQU FALSE ; ACIA: ENABLE DEBUG OUTPUT ACIACNT .EQU 1 ; ACIA: NUMBER OF CHIPS TO DETECT (1-2) @@ -95,24 +115,22 @@ ACIA1CFG .EQU DEFSERCFG ; ACIA 1: SERIAL LINE CONFIG (SEE STD.ASM) SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) SIODEBUG .EQU FALSE ; SIO: ENABLE DEBUG OUTPUT SIOCNT .EQU 2 ; SIO: NUMBER OF CHIPS TO DETECT (1-2), 2 CHANNELS PER CHIP -SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO0CTCC .EQU -1 ; SIO 0: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO0BASE .EQU $80 ; SIO 0: REGISTERS BASE ADR SIO0ACLK .EQU CPUOSC ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0ADIV .EQU 1 ; SIO 0A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0ACFG .EQU DEFSERCFG ; SIO 0A: SERIAL LINE CONFIG +SIO0ACTCC .EQU -1 ; SIO 0A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO0BCLK .EQU CPUOSC ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0BDIV .EQU 1 ; SIO 0B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0BCFG .EQU DEFSERCFG ; SIO 0B: SERIAL LINE CONFIG -SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO1CTCC .EQU -1 ; SIO 1: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0BCTCC .EQU -1 ; SIO 0B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO1BASE .EQU $84 ; SIO 1: REGISTERS BASE ADR SIO1ACLK .EQU CPUOSC ; SIO 1A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1ADIV .EQU 1 ; SIO 1A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1ACFG .EQU DEFSERCFG ; SIO 1A: SERIAL LINE CONFIG +SIO1ACTCC .EQU -1 ; SIO 1A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO1BCLK .EQU CPUOSC ; SIO 1B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1BDIV .EQU 1 ; SIO 1B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1BCFG .EQU DEFSERCFG ; SIO 1B: SERIAL LINE CONFIG +SIO1BCTCC .EQU -1 ; SIO 1B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE ; XIOCFG .EQU DEFSERCFG ; XIO: SERIAL LINE CONFIG ; @@ -120,18 +138,17 @@ VDUENABLE .EQU FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSMODE .EQU TMSMODE_RC ; TMS: DRIVER MODE: TMSMODE_[SCG/N8] +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -175,12 +192,15 @@ PPIDE2A8BIT .EQU FALSE ; PPIDE 2A (MASTER): 8 BIT XFER PPIDE2B8BIT .EQU FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER ; SDENABLE .EQU FALSE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) -SDMODE .EQU SDMODE_PPI ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4|SC|MT] +SDMODE .EQU SDMODE_MT ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4|SC|MT] SDCNT .EQU 1 ; SD: NUMBER OF SD CARD DEVICES (1-2), FOR DSD & SC ONLY SDTRACE .EQU 1 ; SD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) SDCSIOFAST .EQU FALSE ; SD: ENABLE TABLE-DRIVEN BIT INVERTER IN CSIO MODE ; PRPENABLE .EQU FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) +PRPSDENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER SD CARD SUPPORT +PRPSDTRACE .EQU 1 ; PRP: SD CARD TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +PRPCONENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER VIDEO/KBD SUPPORT ; PPPENABLE .EQU FALSE ; PPP: ENABLE ZETA PARALLEL PORT PROPELLER BOARD DRIVER (PPP.ASM) ; @@ -192,4 +212,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index 260a763d..495c7286 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -14,20 +14,21 @@ #DEFINE PLATFORM_NAME "SBC" ; PLATFORM .EQU PLT_SBC ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 8000000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 0 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_SBC ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +MEMMGR .EQU MM_SBC ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER MPCL_RAM .EQU $78 ; SBC MEM MGR RAM PAGE SELECT REG (WRITE ONLY) MPCL_ROM .EQU $7C ; SBC MEM MGR ROM PAGE SELECT REG (WRITE ONLY) ; @@ -38,8 +39,16 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT -CTCMODE .EQU CTCMODE_ZP ; CTC MODE: CTCMODE_[ZP|Z2|EZ|RC] -CTCBASE .EQU $80 ; CTC BASE I/O ADDRESS +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT +CTCBASE .EQU $B0 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU TRUE ; ENABLE CTC PERIODIC TIMER +CTCMODE .EQU CTCMODE_CTR ; CTC MODE: CTCMODE_[NONE|CTR|TIM16|TIM256] +CTCPRE .EQU 256 ; PRESCALE CONSTANT (1-256) +CTCPRECH .EQU 2 ; PRESCALE CHANNEL (0-3) +CTCTIMCH .EQU 3 ; TIMER CHANNEL (0-3) +CTCOSC .EQU 614400 ; CTC CLOCK FREQUENCY +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS @@ -71,6 +80,8 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS @@ -83,20 +94,21 @@ UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) SIODEBUG .EQU FALSE ; SIO: ENABLE DEBUG OUTPUT SIOCNT .EQU 1 ; SIO: NUMBER OF CHIPS TO DETECT (1-2), 2 CHANNELS PER CHIP -SIO0MODE .EQU SIOMODE_ZP ; SIO 0: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO0CTCC .EQU -1 ; SIO 0: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0MODE .EQU SIOMODE_ZP ; SIO 0: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO0BASE .EQU $B0 ; SIO 0: REGISTERS BASE ADR -SIO0ACLK .EQU 4915200 ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0ADIV .EQU 8 ; SIO 0A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) +SIO0ACLK .EQU (4915200/8) ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 SIO0ACFG .EQU DEFSERCFG ; SIO 0A: SERIAL LINE CONFIG -SIO0BCLK .EQU 4915200 ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0BDIV .EQU 8 ; SIO 0B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) +SIO0ACTCC .EQU -1 ; SIO 0A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO0BCLK .EQU (4915200/8) ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 SIO0BCFG .EQU DEFSERCFG ; SIO 0B: SERIAL LINE CONFIG +SIO0BCTCC .EQU -1 ; SIO 0B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE ; XIOCFG .EQU DEFSERCFG ; XIO: SERIAL LINE CONFIG ; @@ -106,19 +118,18 @@ CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) TMSMODE .EQU TMSMODE_SCG ; TMS: DRIVER MODE: TMSMODE_[SCG/N8] +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) VGASIZ .EQU V80X25 ; VGA: DISPLAY FORMAT [V80X25|V80X30|V80X43] ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_SCG ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM +; ; FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_DIO3 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_DIO3 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -187,4 +198,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) UFBASE .EQU $0C ; UF: REGISTERS BASE ADR ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +; +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_SCG ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_scz180.asm b/Source/HBIOS/cfg_scz180.asm index e28e4cde..f8fc2c1a 100644 --- a/Source/HBIOS/cfg_scz180.asm +++ b/Source/HBIOS/cfg_scz180.asm @@ -14,20 +14,21 @@ #DEFINE PLATFORM_NAME "SCZ180" ; PLATFORM .EQU PLT_SCZ180 ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z180 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 18432000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 2 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_Z180 ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] +MEMMGR .EQU MM_Z180 ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER RAMBIAS .EQU 512 ; OFFSET OF START OF RAM IN PHYSICAL ADDRESS SPACE ; Z180_BASE .EQU $C0 ; Z180: I/O BASE ADDRESS FOR INTERNAL REGISTERS @@ -41,6 +42,11 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT +CTCBASE .EQU $88 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU FALSE ; ENABLE CTC PERIODIC TIMER +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $0D ; DIAGNOSTIC PORT ADDRESS @@ -68,9 +74,18 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +DUARTCNT .EQU 2 ; DUART: NUMBER OF CHIPS TO DETECT (1-2) +DUART0BASE .EQU $A0 ; DUART 0: BASE ADDRESS OF CHIP +DUART0ACFG .EQU DEFSERCFG ; DUART 0A: SERIAL LINE CONFIG +DUART0BCFG .EQU DEFSERCFG ; DUART 0B: SERIAL LINE CONFIG +DUART1BASE .EQU $40 ; DUART 1: BASE ADDRESS OF CHIP +DUART1ACFG .EQU DEFSERCFG ; DUART 1A: SERIAL LINE CONFIG +DUART1BCFG .EQU DEFSERCFG ; DUART 1B: SERIAL LINE CONFIG +; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ -UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS +UARTCFG .EQU DEFSERCFG | SER_RTS ; UART: LINE CONFIG FOR UART PORTS UARTSBC .EQU FALSE ; UART: AUTO-DETECT SBC/ZETA ONBOARD UART UARTCAS .EQU FALSE ; UART: AUTO-DETECT ECB CASSETTE UART UARTMFP .EQU FALSE ; UART: AUTO-DETECT MF/PIC UART @@ -78,32 +93,33 @@ UART4 .EQU FALSE ; UART: AUTO-DETECT 4UART UART UARTRC .EQU TRUE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) +ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) SIODEBUG .EQU FALSE ; SIO: ENABLE DEBUG OUTPUT SIOCNT .EQU 2 ; SIO: NUMBER OF CHIPS TO DETECT (1-2), 2 CHANNELS PER CHIP -SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO0CTCC .EQU -1 ; SIO 0: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0MODE .EQU SIOMODE_RC ; SIO 0: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO0BASE .EQU $80 ; SIO 0: REGISTERS BASE ADR SIO0ACLK .EQU 7372800 ; SIO 0A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0ADIV .EQU 1 ; SIO 0A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0ACFG .EQU SER_115200_8N1 ; SIO 0A: SERIAL LINE CONFIG +SIO0ACTCC .EQU -1 ; SIO 0A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO0BCLK .EQU 7372800 ; SIO 0B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO0BDIV .EQU 1 ; SIO 0B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO0BCFG .EQU SER_115200_8N1 ; SIO 0B: SERIAL LINE CONFIG -SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[RC|SMB|ZP|EZZ80] -SIO1CTCC .EQU -1 ; SIO 1: CTC CHANNEL CLOCK SCALER, (0-3), -1 FOR NONE +SIO0BCTCC .EQU -1 ; SIO 0B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE +SIO1MODE .EQU SIOMODE_RC ; SIO 1: CHIP TYPE: SIOMODE_[STD|RC|SMB|ZP] SIO1BASE .EQU $84 ; SIO 1: REGISTERS BASE ADR SIO1ACLK .EQU 7372800 ; SIO 1A: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1ADIV .EQU 1 ; SIO 1A: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1ACFG .EQU SER_115200_8N1 ; SIO 1A: SERIAL LINE CONFIG +SIO1ACTCC .EQU -1 ; SIO 1A: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE SIO1BCLK .EQU 7372800 ; SIO 1B: OSC FREQ IN HZ, ZP=2457600/4915200, RC/SMB=7372800 -SIO1BDIV .EQU 1 ; SIO 1B: SERIAL CLOCK DIVIDER, RC2014/SMB=1, ZP=2/4/8/16/32/64/128/256 (X5) SIO1BCFG .EQU SER_115200_8N1 ; SIO 1B: SERIAL LINE CONFIG +SIO1BCTCC .EQU -1 ; SIO 1B: CTC CHANNEL 0=A, 1=B, 2=C, 3=D, -1 FOR NONE ; XIOCFG .EQU DEFSERCFG ; XIO: SERIAL LINE CONFIG ; @@ -111,18 +127,17 @@ VDUENABLE .EQU FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSMODE .EQU TMSMODE_RC ; TMS: DRIVER MODE: TMSMODE_[SCG/N8] +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -AYMODE .EQU AYMODE_RCZ180 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 2 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -172,6 +187,9 @@ SDTRACE .EQU 1 ; SD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) SDCSIOFAST .EQU FALSE ; SD: ENABLE TABLE-DRIVEN BIT INVERTER IN CSIO MODE ; PRPENABLE .EQU FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) +PRPSDENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER SD CARD SUPPORT +PRPSDTRACE .EQU 1 ; PRP: SD CARD TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +PRPCONENABLE .EQU TRUE ; PRP: ENABLE PROPIO DRIVER VIDEO/KBD SUPPORT ; PPPENABLE .EQU FALSE ; PPP: ENABLE ZETA PARALLEL PORT PROPELLER BOARD DRIVER (PPP.ASM) ; @@ -183,4 +201,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_RCZ180 ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_una.asm b/Source/HBIOS/cfg_una.asm index 058eca9e..10821319 100644 --- a/Source/HBIOS/cfg_una.asm +++ b/Source/HBIOS/cfg_una.asm @@ -16,7 +16,7 @@ PLATFORM .EQU PLT_UNA ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] BIOS .EQU BIOS_UNA ; HARDWARE BIOS: BIOS_[WBW|UNA] ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 18432000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 0 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index c59b5970..788e4dfe 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -14,20 +14,21 @@ #DEFINE PLATFORM_NAME "ZETA" ; PLATFORM .EQU PLT_ZETA ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z80 ; CPU_[Z80|Z180]: CPU FAMILY +CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; BIOS_[WBW|UNA]: HARDWARE BIOS BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 20000000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 0 ; INTERRUPT MODE: 0=NONE, 1=MODE 1, 2=MODE 2 DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SEE STD.ASM) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) -MEMMGR .EQU MM_SBC ; MM_[SBC|Z2|N8|Z180]: MEMORY MANAGER +MEMMGR .EQU MM_SBC ; MM_[SBC|Z2|N8|Z180|Z280|ZRC]: MEMORY MANAGER MPCL_RAM .EQU $78 ; SBC MEM MGR RAM PAGE SELECT REG (WRITE ONLY) MPCL_ROM .EQU $7C ; SBC MEM MGR ROM PAGE SELECT REG (WRITE ONLY) ; @@ -39,6 +40,8 @@ KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU FALSE ; ENABLE ZILOG CTC SUPPORT ; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +; DIAGENABLE .EQU FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS DIAGDISKIO .EQU TRUE ; ENABLES DISK I/O ACTIVITY ON DIAGNOSTIC LEDS @@ -60,10 +63,12 @@ DSRTCCHG .EQU FALSE ; DSRTC: FORCE BATTERY CHARGE ON (USE WITH CAUTION!!!) BQRTCENABLE .EQU FALSE ; BQRTC: ENABLE BQ4845 CLOCK DRIVER (BQRTC.ASM) BQRTC_BASE .EQU $50 ; BQRTC: I/O BASE ADDRESS ; +INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) +; HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; -INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) ; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ @@ -77,6 +82,8 @@ UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) @@ -87,17 +94,16 @@ VDUENABLE .EQU FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU TRUE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_ZETA ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_ZETA ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 1 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -135,4 +141,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_NONE ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_zeta2.asm b/Source/HBIOS/cfg_zeta2.asm index 6aed5e08..bf9ac447 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -14,13 +14,14 @@ #DEFINE PLATFORM_NAME "ZETA V2" ; PLATFORM .EQU PLT_ZETA2 ; PLT_[SBC|ZETA|ZETA2|N8|MK4|UNA|RCZ80|RCZ180|EZZ80|SCZ180|DYNO] -CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180] +CPUFAM .EQU CPU_Z80 ; CPU FAMILY: CPU_[Z80|Z180|Z280] BIOS .EQU BIOS_WBW ; HARDWARE BIOS: BIOS_[WBW|UNA] BATCOND .EQU FALSE ; ENABLE LOW BATTERY WARNING MESSAGE HBIOS_MUTEX .EQU FALSE ; ENABLE REENTRANT CALLS TO HBIOS (ADDS OVERHEAD) USELZSA2 .EQU TRUE ; ENABLE FONT COMPRESSION +TICKFREQ .EQU 50 ; DESIRED PERIODIC TIMER INTERRUPT FREQUENCY (HZ) ; -BOOT_TIMEOUT .EQU 0 ; AUTO BOOT TIMEOUT IN SECONDS, 0 TO DISABLE +BOOT_TIMEOUT .EQU -1 ; AUTO BOOT TIMEOUT IN SECONDS, -1 TO DISABLE, 0 FOR IMMEDIATE ; CPUOSC .EQU 20000000 ; CPU OSC FREQ IN MHZ INTMODE .EQU 2 ; INTERRUPTS: 0=NONE, 1=MODE 1, 2=MODE 2 @@ -41,8 +42,16 @@ KIOENABLE .EQU FALSE ; ENABLE ZILOG KIO SUPPORT KIOBASE .EQU $80 ; KIO BASE I/O ADDRESS ; CTCENABLE .EQU TRUE ; ENABLE ZILOG CTC SUPPORT -CTCMODE .EQU CTCMODE_Z2 ; CTC MODE: CTCMODE_[ZP|Z2|EZ|RC] +CTCDEBUG .EQU FALSE ; ENABLE CTC DRIVER DEBUG OUTPUT CTCBASE .EQU $20 ; CTC BASE I/O ADDRESS +CTCTIMER .EQU TRUE ; ENABLE CTC PERIODIC TIMER +CTCMODE .EQU CTCMODE_CTR ; CTC MODE: CTCMODE_[NONE|CTR|TIM16|TIM256] +CTCPRE .EQU 256 ; PRESCALE CONSTANT (1-256) +CTCPRECH .EQU 0 ; PRESCALE CHANNEL (0-3) +CTCTIMCH .EQU 1 ; TIMER CHANNEL (0-3) +CTCOSC .EQU 921600 ; CTC CLOCK FREQUENCY +; +EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION ; DIAGENABLE .EQU FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT DIAGPORT .EQU $00 ; DIAGNOSTIC PORT ADDRESS @@ -70,6 +79,8 @@ INTRTCENABLE .EQU FALSE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM) HTIMENABLE .EQU FALSE ; ENABLE SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; ENABLE SIMH CLOCK DRIVER (SIMRTC.ASM) ; +DUARTENABLE .EQU FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +; UARTENABLE .EQU TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) UARTOSC .EQU 1843200 ; UART: OSC FREQUENCY IN MHZ UARTCFG .EQU DEFSERCFG ; UART: LINE CONFIG FOR UART PORTS @@ -82,6 +93,8 @@ UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERIAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) @@ -92,17 +105,16 @@ VDUENABLE .EQU FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) CVDUENABLE .EQU FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) NECENABLE .EQU FALSE ; NEC: ENABLE NEC UPD7220 VIDEO/KBD DRIVER (NEC.ASM) TMSENABLE .EQU FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSTIMENABLE .EQU FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; -SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) -; -AYENABLE .EQU FALSE ; AY: ENABLE AY PSG SOUND DRIVER -; MDENABLE .EQU TRUE ; MD: ENABLE MEMORY (ROM/RAM) DISK DRIVER (MD.ASM) MDTRACE .EQU 1 ; MD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +MDFFENABLE .EQU FALSE ; MD: ENABLE FLASH FILE SYSTEM ; FDENABLE .EQU TRUE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) -FDMODE .EQU FDMODE_ZETA2 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|DIDE|N8|DIO3|DYNO] +FDMODE .EQU FDMODE_ZETA2 ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] +FDCNT .EQU 1 ; FD: NUMBER OF FLOPPY DRIVES ON THE INTERFACE (1-2) FDTRACE .EQU 1 ; FD: TRACE LEVEL (0=NO,1=FATAL,2=ERRORS,3=ALL) FDMEDIA .EQU FDM144 ; FD: DEFAULT MEDIA FORMAT FDM[720|144|360|120|111] FDMEDIAALT .EQU FDM720 ; FD: ALTERNATE MEDIA FORMAT FDM[720|144|360|120|111] @@ -140,4 +152,11 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) ; -EIPCENABLE .EQU FALSE ; EIPC: ENABLE Z80 EIPC (Z84C15) INITIALIZATION +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +SN7CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 + +AY38910ENABLE .EQU FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AY_CLK .EQU CPUOSC / 4 ; DEFAULT TO CPUOSC / 4 +AYMODE .EQU AYMODE_NONE ; AY: DRIVER MODE: AYMODE_[SCG/N8/RCZ80/RCZ180] +SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/ctc.asm b/Source/HBIOS/ctc.asm index 814fd110..d4c6b156 100644 --- a/Source/HBIOS/ctc.asm +++ b/Source/HBIOS/ctc.asm @@ -5,53 +5,94 @@ ; DISPLAY CONFIGURATION DETAILS ;______________________________________________________________________________________________________________________ ; +CTC_DEFCFG .EQU %01010011 ; CTC DEFAULT CONFIG +CTC_CTRCFG .EQU %01010111 ; CTC COUNTER MODE CONFIG +CTC_TIM16CFG .EQU %00010111 ; CTC TIMER/16 MODE CONFIG +CTC_TIM256CFG .EQU %00110111 ; CTC TIMER/256 MODE CONFIG +CTC_TIMCFG .EQU %11010111 ; CTC TIMER CHANNEL CONFIG + ; |||||||+-- CONTROL WORD FLAG + ; ||||||+--- SOFTWARE RESET + ; |||||+---- TIME CONSTANT FOLLOWS + ; ||||+----- AUTO TRIGGER WHEN TIME CONST LOADED + ; |||+------ RISING EDGE TRIGGER + ; ||+------- TIMER MODE PRESCALER (0=16, 1=256) + ; |+-------- COUNTER MODE + ; +--------- INTERRUPT ENABLE +; +#IF (CTCTIMER) +; ; ONLY IM2 IMPLEMENTED BELOW. I DON'T SEE ANY REASONABLE WAY TO ; IMPLEMENT AN IM1 TIMER BECAUSE THE CTC PROVIDES NO WAY TO ; DETERMINE IF IT WAS THE CAUSE OF AN INTERRUPT OR A WAY TO ; DETERMINE WHICH CHANNEL CAUSED AN INTERRUPT. ; -#IF (INTMODE != 2) + #IF (INTMODE != 2) .ECHO "*** ERROR: CTC REQUIRES INTMODE 2!!!\n" !!! ; FORCE AN ASSEMBLY ERROR -#ENDIF -; -; CONFIGURATION -; -#IF (CTCMODE == CTCMODE_ZP) -CTCPC .EQU CTCC ; PRESCALE CHANNEL -CTCPCC .EQU 0 ; PRESCALE CHANNEL CONSTANT -CTCTC .EQU CTCD ; TIMER CHANNEL -CTCTCC .EQU 48 ; TIMER CHANNEL CONSTANT -CTCTIVT .EQU INT_CTC0D ; TIMER CHANNEL IVT ENTRY -#ENDIF + #ENDIF +; +CTC_PREIO .EQU CTCBASE + CTCPRECH +CTC_SCLIO .EQU CTCBASE + CTCTIMCH +; + #IF (CTCMODE == CTCMODE_CTR) +CTC_PRECFG .EQU CTC_CTRCFG +CTC_PRESCL .EQU 1 + #ENDIF + #IF (CTCMODE == CTCMODE_TIM16) +CTC_PRECFG .EQU CTC_TIM16CFG +CTC_PRESCL .EQU 16 + #ENDIF + #IF (CTCMODE == CTCMODE_TIM256) +CTC_PRECFG .EQU CTC_TIM256CFG +CTC_PRESCL .EQU 256 + #ENDIF +; +CTC_DIV .EQU CTCOSC / CTC_PRESCL / TICKFREQ +; +CTC_DIVHI .EQU CTCPRE +CTC_DIVLO .EQU (CTC_DIV / CTC_DIVHI) +; + .ECHO "CTC DIVISOR: " + .ECHO CTC_DIV + .ECHO ", HI: " + .ECHO CTC_DIVHI + .ECHO ", LO: " + .ECHO CTC_DIVLO + .ECHO "\n" +; + #IF ((CTC_DIV == 0) | (CTC_DIV > $FFFF)) + .ECHO "COMPUTED CTC DIVISOR IS UNUSABLE!\n" + !!! + #ENDIF +; + #IF ((CTC_DIVHI > $100) | (CTC_DIVLO > $100)) + .ECHO "COMPUTED CTC DIVISOR IS UNUSABLE!\n" + !!! + #ENDIF +; + #IF ((CTC_DIVHI * CTC_DIVLO * CTC_PRESCL * TICKFREQ) != CTCOSC) + .ECHO "COMPUTED CTC DIVISOR IS UNUSABLE!\n" + !!! + #ENDIF +; +CTCTIVT .EQU INT_CTC0A + CTCTIMCH ; -#IF (CTCMODE == CTCMODE_Z2) -CTCPC .EQU CTCA ; PRESCALE CHANNEL -CTCPCC .EQU 0 ; PRESCALE CHANNEL CONSTANT -CTCTC .EQU CTCB ; TIMER CHANNEL -CTCTCC .EQU 72 ; TIMER CHANNEL CONSTANT -CTCTIVT .EQU INT_CTC0B ; TIMER CHANNEL IVT ENTRY #ENDIF ; -#IF (CTCMODE == CTCMODE_EZ) -CTCPC .EQU CTCC ; PRESCALE CHANNEL -CTCPCC .EQU 0 ; PRESCALE CHANNEL CONSTANT -CTCTC .EQU CTCD ; TIMER CHANNEL -CTCTCC .EQU 72 ; TIMER CHANNEL CONSTANT -CTCTIVT .EQU INT_CTC0D ; TIMER CHANNEL IVT ENTRY -#ENDIF ; -#IF (CTCMODE == CTCMODE_RC) -CTCPC .EQU CTCC ; PRESCALE CHANNEL -CTCPCC .EQU 0 ; PRESCALE CHANNEL CONSTANT -CTCTC .EQU CTCD ; TIMER CHANNEL -CTCTCC .EQU 144 ; TIMER CHANNEL CONSTANT -CTCTIVT .EQU INT_CTC0D ; TIMER CHANNEL IVT ENTRY -#ENDIF ; +CTC_PREINIT: ; + ; RESET ALL CTC CHANNELS + LD B,4 ; 4 CHANNELS + LD C,CTCBASE ; FIRST CHANNEL PORT +CTC_PREINIT1: + LD A,CTC_DEFCFG ; CTC DEFAULT CONFIG + OUT (C),A ; CTC COMMAND + INC C ; NEXT CHANNEL PORT + DJNZ CTC_PREINIT1 ; -CTC_PREINIT: +#IF (CTCTIMER) ; SETUP TIMER INTERRUPT IVT SLOT LD HL,HB_TIMINT ; TIMER INT HANDLER ADR LD (IVT(CTCTIVT)),HL ; IVT ENTRY FOR TIMER CHANNEL @@ -59,40 +100,26 @@ CTC_PREINIT: ; CTC USES 4 CONSECUTIVE VECTOR POSITIONS, ONE FOR ; EACH CHANNEL. BELOW WE SET THE BASE VECTOR TO THE ; START OF THE IVT, SO THE FIRST FOUR ENTIRES OF THE - ; IVT CORRESPOND TO CTC CHANNELS A-D + ; IVT CORRESPOND TO CTC CHANNELS A-D. LD A,0 OUT (CTCBASE),A ; SETUP CTC BASE INT VECTOR ; ; IN ORDER TO DIVIDE THE CTC INPUT CLOCK DOWN TO THE - ; DESIRED 50 HZ PERIODIC INTERRUPT, WE NEED TO CONFIGURE ONE + ; DESIRED PERIODIC INTERRUPT, WE NEED TO CONFIGURE ONE ; CTC CHANNEL AS A PRESCALER AND ANOTHER AS THE ACTUAL ; TIMER INTERRUPT. THE PRESCALE CHANNEL OUTPUT MUST BE WIRED ; TO THE TIMER CHANNEL TRIGGER INPUT VIA HARDWARE. - LD A,%01010111 ; PRESCALE CHANNEL CONTROL WORD VALUE - ; |||||||+-- 1=CONTROL WORD FLAG - ; ||||||+--- 1=SOFTWARE RESET - ; |||||+---- 1=TIME CONSTANT FOLLOWS - ; ||||+----- 0=AUTO TRIGGER WHEN TIME CONST LOADED - ; |||+------ 1=RISING EDGE TRIGGER - ; ||+------- 0=PRESCALER OF 16 (NOT USED) - ; |+-------- 1=COUNTER MODE - ; +--------- 0=NO INTERRUPTS - OUT (CTCPC),A ; SETUP PRESCALE CHANNEL - LD A,CTCPCC ; PRESCALE CHANNEL CONSTANT - OUT (CTCPC),A ; SET PRESCALE CONSTANT - ; - LD A,%11010111 ; TIMER CHANNEL CONTROL WORD VALUE - ; |||||||+-- 1=CONTROL WORD FLAG - ; ||||||+--- 1=SOFTWARE RESET - ; |||||+---- 1=TIME CONSTANT FOLLOWS - ; ||||+----- 0=AUTO TRIGGER WHEN TIME CONST LOADED - ; |||+------ 1=RISING EDGE TRIGGER - ; ||+------- 0=PRESCALER OF 16 (NOT USED) - ; |+-------- 1=COUNTER MODE - ; +--------- 1=ENABLE INTERRUPTS - OUT (CTCTC),A ; SETUP TIMER CHANNEL - LD A,CTCTCC ; TIMER CHANNEL CONSTANT - OUT (CTCTC),A ; SET TIMER CONSTANT + LD A,CTC_PRECFG ; PRESCALE CHANNEL CONFIGURATION + OUT (CTC_PREIO),A ; SETUP PRESCALE CHANNEL + LD A,CTC_DIVHI & $FF ; PRESCALE CHANNEL CONSTANT + OUT (CTC_PREIO),A ; SET PRESCALE CONSTANT +; + LD A,CTC_TIMCFG ; TIMER CHANNEL CONTROL WORD VALUE + OUT (CTC_SCLIO),A ; SETUP TIMER CHANNEL + LD A,CTC_DIVLO & $FF ; TIMER CHANNEL CONSTANT + OUT (CTC_SCLIO),A ; SET TIMER CONSTANT +; +#ENDIF ; XOR A RET @@ -103,22 +130,48 @@ CTC_INIT: ; MINIMAL INIT CTC_PRTCFG: ; ANNOUNCE PORT CALL NEWLINE ; FORMATTING - PRTS("CTC: MODE=$") ; FORMATTING -#IF (CTCMODE == CTCMODE_ZP) - PRTS("ZP$") -#ENDIF -#IF (CTCMODE == CTCMODE_Z2) - PRTS("Z2$") -#ENDIF -#IF (CTCMODE == CTCMODE_EZ) - PRTS("EZ$") -#ENDIF -#IF (CTCMODE == CTCMODE_RC) - PRTS("RC$") -#ENDIF + PRTS("CTC:$") ; FORMATTING +; PRTS(" IO=0x$") ; FORMATTING LD A,CTCBASE ; GET BASE PORT CALL PRTHEXBYTE ; PRINT BASE PORT +; +#IF (CTCTIMER) +; + PRTS(" MODE=$") ; FORMATTING + #IF (CTCMODE == CTCMODE_CTR) + PRTS("CTR$") + #ENDIF + #IF (CTCMODE == CTCMODE_TIM16) + PRTS("TIM16$") + #ENDIF + #IF (CTCMODE == CTCMODE_TIM256) + PRTS("TIM256$") + #ENDIF +; + PRTS(" DIVHI=$") + LD A,CTC_DIVHI & $FF + CALL PRTHEXBYTE +; + PRTS(" DIVLO=$") + LD A,CTC_DIVLO & $FF + CALL PRTHEXBYTE +; + #IF (CTCDEBUG) + PRTS(" PREIO=$") + LD A,CTC_PREIO + CALL PRTHEXBYTE +; + PRTS(" SCLIO=$") + LD A,CTC_SCLIO + CALL PRTHEXBYTE +; + PRTS(" DIV=$") + LD BC,CTC_DIV + CALL PRTHEXWORD + #ENDIF +; +#ENDIF ; XOR A RET diff --git a/Source/HBIOS/cvdu.asm b/Source/HBIOS/cvdu.asm index 9ee98c40..558f61d0 100644 --- a/Source/HBIOS/cvdu.asm +++ b/Source/HBIOS/cvdu.asm @@ -96,6 +96,7 @@ CVDU_FNTBL: .DW KBD_READ #IF (($ - CVDU_FNTBL) != (VDA_FNCNT * 2)) .ECHO "*** INVALID CVDU FUNCTION TABLE ***\n" + !!!!! #ENDIF CVDU_VDAINI: @@ -112,11 +113,11 @@ CVDU_VDAQRY: LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET XOR A ; SIGNAL SUCCESS RET - + CVDU_VDARES: LD A,$0E ; ATTRIBUTE IS STANDARD WHITE ON BLACK LD (CVDU_ATTR),A ; SAVE IT - + LD DE,0 ; ROW = 0, COL = 0 CALL CVDU_XY ; SEND CURSOR TO TOP LEFT LD A,' ' ; BLANK THE SCREEN @@ -124,24 +125,29 @@ CVDU_VDARES: CALL CVDU_FILL ; DO IT LD DE,0 ; ROW = 0, COL = 0 CALL CVDU_XY ; SEND CURSOR TO TOP LEFT - + XOR A RET CVDU_VDADEV: LD D,VDADEV_CVDU ; D := DEVICE TYPE LD E,0 ; E := PHYSICAL UNIT IS ALWAYS ZERO + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,CVDU_BASE ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET - + CVDU_VDASCS: - CALL PANIC ; NOT IMPLEMENTED (YET) - + CALL SYSCHK ; NOT IMPLEMENTED (YET) + LD A,ERR_NOTIMPL + OR A + RET + CVDU_VDASCP: CALL CVDU_XY ; SET CURSOR POSITION XOR A ; SIGNAL SUCCESS RET - + CVDU_VDASAT: ; INCOMING IS: -----RUB (R=REVERSE, U=UNDERLINE, B=BLINK) ; TRANSFORM TO: -RUB---- @@ -158,7 +164,7 @@ CVDU_VDASAT: LD (CVDU_ATTR),A ; AND SAVE THE RESULT XOR A ; SIGNAL SUCCESS RET - + CVDU_VDASCO: ; INCOMING IS: IBGRIBGR (I=INTENSITY, B=BLUE, G=GREEN, R=RED) ; TRANSFORM TO: ----RGBI (DISCARD BACKGROUND COLOR IN HIGH NIBBLE) @@ -175,13 +181,13 @@ CVDU_VDASCO1: LD (CVDU_ATTR),A ; AND SAVE THE RESULT XOR A ; SIGNAL SUCCESS RET - + CVDU_VDAWRC: LD A,E ; CHARACTER TO WRITE GOES IN A CALL CVDU_PUTCHAR ; PUT IT ON THE SCREEN XOR A ; SIGNAL SUCCESS RET - + CVDU_VDAFIL: LD A,E ; FILL CHARACTER GOES IN A EX DE,HL ; FILL LENGTH GOES IN DE @@ -197,7 +203,7 @@ CVDU_VDACPY: POP BC ; RECOVER LENGTH IN BC LD DE,(CVDU_POS) ; PUT DEST IN DE JP CVDU_BLKCPY ; DO A BLOCK COPY - + CVDU_VDASCR: LD A,E ; LOAD E INTO A OR A ; SET FLAGS @@ -246,7 +252,7 @@ CVDU_WRX: ;---------------------------------------------------------------------- ; READ M8563 REGISTERS ; CVDU_RD READS VDU REGISTER SPECIFIED IN C AND RETURNS VALUE IN A -; CVDU_RDX READS VDU REGISTER PAIR SPECIFIED BY C, C+1 +; CVDU_RDX READS VDU REGISTER PAIR SPECIFIED BY C, C+1 ; AND RETURNS VALUE IN HL ;---------------------------------------------------------------------- ; @@ -317,7 +323,7 @@ CVDU_CRTINIT1: ; ASSUMES THAT VDU RAM SIZE IS SET FOR 64KB ABOVE ; A. WRITE ZERO TO ADDRESS $0000 ; B. WRITE NON-ZERO TO ADDRESS $0100 -; C. CHECK THE VALUE IN ADDRESS $0000; IF IT CHANGED, +; C. CHECK THE VALUE IN ADDRESS $0000; IF IT CHANGED, ; 16K DRAM CHIPS INSTALLED; IF NOT, 64K DRAM CHIPS INSTALLED ; IF 16KB RAM DETECTED, ADJUST VDU REGISTERS APPROPRIATELY ; @@ -367,7 +373,7 @@ CVDU_LOADFONT: LD (CVDU_STACK),SP ; SAVE STACK LD HL,(CVDU_STACK) ; AND SHIFT IT LD DE,$2000 ; DOWN 4KB TO - CCF ; CREATE A + OR A ; CREATE A SBC HL,DE ; DECOMPRESSION BUFFER LD SP,HL ; HL POINTS TO BUFFER EX DE,HL ; START OF STACK BUFFER @@ -424,7 +430,7 @@ CVDU_XY2IDX: RET ; RETURN ; ;---------------------------------------------------------------------- -; WRITE VALUE IN A TO CURRENT VDU BUFFER POSTION, ADVANCE CURSOR +; WRITE VALUE IN A TO CURRENT VDU BUFFER POSITION, ADVANCE CURSOR ;---------------------------------------------------------------------- ; CVDU_PUTCHAR: @@ -436,7 +442,7 @@ CVDU_PUTCHAR: CALL CVDU_WRX ; DO IT ; PUT THE CHARACTER THERE - POP AF ; RECOVER CHARACTER VALLUE TO WRITE + POP AF ; RECOVER CHARACTER VALUE TO WRITE LD C,31 ; DATA REGISTER CALL CVDU_WR ; DO IT @@ -475,19 +481,19 @@ CVDU_FILL: POP DE ; RECOVER FILL COUNT LD A,(CVDU_ATTR) ; SET ATTRIBUTE VALUE FOR ATTRIBUTE FILL JR CVDU_FILL1 ; DO ATTRIBUTE FILL AND RETURN - + CVDU_FILL1: LD B,A ; SAVE REQUESTED FILL VALUE - + ; CHECK FOR VALID FILL LENGTH LD A,D ; LOAD D OR E ; OR WITH E RET Z ; BAIL OUT IF LENGTH OF ZERO SPECIFIED - + ; POINT TO BUFFER LOCATION TO START FILL LD C,18 ; UPDATE ADDRESS REGISTER PAIR CALL CVDU_WRX ; DO IT - + ; SET MODE TO BLOCK WRITE LD C,24 ; BLOCK MODE CONTROL REGISTER CALL CVDU_RD ; GET CURRENT VALUE @@ -499,7 +505,7 @@ CVDU_FILL1: LD C,31 ; DATA REGISTER CALL CVDU_WR ; DO IT DEC DE ; REFLECT ONE CHARACTER WRITTEN - + ; LOOP TO DO BULK WRITE (UP TO 255 BYTES PER LOOP) EX DE,HL ; NOW USE HL FOR COUNT LD C,30 ; BYTE COUNT REGISTER @@ -527,7 +533,7 @@ CVDU_SCROLL: LD A,' ' ; CHAR VALUE TO FILL NEW EXPOSED LINE LD HL,0 ; SOURCE ADDRESS OF CHARACER BUFFER CALL CVDU_SCROLL1 ; SCROLL CHARACTER BUFFER - + ; SCROLL THE ATTRIBUTE BUFFER LD A,(CVDU_ATTR) ; ATTRIBUTE VALUE TO FILL NEW EXPOSED LINE LD HL,$800 ; SOURCE ADDRESS OF ATTRIBUTE BUFFER @@ -535,7 +541,7 @@ CVDU_SCROLL: CVDU_SCROLL1: PUSH AF ; SAVE FILL VALUE FOR NOW - + ; SET MODE TO BLOCK COPY LD C,24 ; BLOCK MODE CONTROL REGISTER CALL CVDU_RD ; GET CURRENT VALUE @@ -563,13 +569,13 @@ CVDU_SCROLL2: ; LOOP TILL DONE WITH ALL LINES DJNZ CVDU_SCROLL2 ; REPEAT FOR ALL LINES - + ; SET MODE TO BLOCK WRITE TO CLEAR NEW LINE EXPOSED BY SCROLL LD C,24 ; BLOCK MODE CONTROL REGISTER CALL CVDU_RD ; GET CURRENT VALUE AND $7F ; CLEAR BIT 7 FOR FILL MODE CALL CVDU_WR ; DO IT - + ; SET VALUE TO WRITE POP AF ; RESTORE THE FILL VALUE PASSED IN LD C,31 ; DATA REGISTER @@ -579,7 +585,7 @@ CVDU_SCROLL2: LD A,CVDU_COLS - 1 ; SET WRITE COUNT TO LINE LENGTH - 1 (1 CHAR ALREADY WRITTEN) LD C,30 ; WORD COUNT REGISTER CALL CVDU_WR ; DO IT - + RET ; ;---------------------------------------------------------------------- @@ -591,7 +597,7 @@ CVDU_RSCROLL: LD A,' ' ; CHAR VALUE TO FILL NEW EXPOSED LINE LD HL,$0 + ((CVDU_ROWS - 1) * CVDU_COLS) ; SOURCE ADDRESS OF CHARACER BUFFER CALL CVDU_RSCROLL1 ; SCROLL CHARACTER BUFFER - + ; SCROLL THE ATTRIBUTE BUFFER LD A,(CVDU_ATTR) ; ATTRIBUTE VALUE TO FILL NEW EXPOSED LINE LD HL,$800 + ((CVDU_ROWS - 1) * CVDU_COLS) ; SOURCE ADDRESS OF ATTRIBUTE BUFFER @@ -599,7 +605,7 @@ CVDU_RSCROLL: CVDU_RSCROLL1: PUSH AF ; SAVE FILL VALUE FOR NOW - + ; SET MODE TO BLOCK COPY LD C,24 ; BLOCK MODE CONTROL REGISTER CALL CVDU_RD ; GET CURRENT VALUE @@ -629,7 +635,7 @@ CVDU_RSCROLL2: CALL CVDU_WR ; DO IT DJNZ CVDU_RSCROLL2 ; REPEAT FOR ALL LINES - + ; SET FILL DESTINATION (USING HL PASSED IN) LD C,18 ; UPDATE ADDRESS (DESTINATION) REGISTER CALL CVDU_WRX ; DO IT @@ -639,7 +645,7 @@ CVDU_RSCROLL2: CALL CVDU_RD ; GET CURRENT VALUE AND $7F ; CLEAR BIT 7 FOR FILL MODE CALL CVDU_WR ; DO IT - + ; SET VALUE TO WRITE POP AF ; RESTORE THE FILL VALUE PASSED IN LD C,31 ; DATA REGISTER @@ -649,7 +655,7 @@ CVDU_RSCROLL2: LD A,CVDU_COLS - 1 ; SET WRITE COUNT TO LINE LENGTH - 1 (1 CHAR ALREADY WRITTEN) LD C,30 ; WORD COUNT REGISTER CALL CVDU_WR ; DO IT - + RET ; ;---------------------------------------------------------------------- diff --git a/Source/HBIOS/dbgmon.asm b/Source/HBIOS/dbgmon.asm index 9e4c8a3a..665bdfbe 100644 --- a/Source/HBIOS/dbgmon.asm +++ b/Source/HBIOS/dbgmon.asm @@ -104,6 +104,10 @@ SERIALCMDLOOP: JP Z,FILLMEM ; FILL MEMORY COMMAND CP 'H' ; IS IT A "H" (Y/N) JP Z,HELP ; HELP COMMAND + CP 'S' ; IS IT A "H" (Y/N) + JP Z,STOP ; STOP COMMAND + CP 'X' ; IS IT A "X" (Y/N) + JP Z,EXIT ; EXIT COMMAND LD HL,TXT_COMMAND ; POINT AT ERROR TEXT CALL PRTSTRH ; PRINT COMMAND LABEL @@ -146,10 +150,37 @@ BOOT: CALL $FFFD ; DO IT (RST 08 NOT SAFE HERE) JP 0 ; JUMP TO RESTART ADDRESS #ELSE - LD A,BID_BOOT ; BOOT BANK - LD HL,0 ; ADDRESS ZERO - CALL HB_BNKCALL ; DOES NOT RETURN + ;LD A,BID_BOOT ; BOOT BANK + ;LD HL,0 ; ADDRESS ZERO + ;CALL HB_BNKCALL ; DOES NOT RETURN + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_COLD ; COLD START + CALL $FFF0 ; CALL HBIOS #ENDIF +; +;__EXIT_______________________________________________________________________ +; +; PERFORM EXIT ACTION +;_____________________________________________________________________________ +; +EXIT: +#IF (BIOS == BIOS_UNA) + JR BOOT +#ELSE + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_WARM ; WARM START + CALL $FFF0 ; CALL HBIOS +#ENDIF +; +;__STOP_______________________________________________________________________ +; +; PERFORM STOP ACTION (HALT SYSTEM) +;_____________________________________________________________________________ +; +STOP: + DI + HALT +; ;__RUN________________________________________________________________________ ; ; TRANSFER OUT OF MONITOR, USER OPTION "R" @@ -912,6 +943,8 @@ TXT_HELP .TEXT "\r\nMonitor Commands (all values in hex):" .TEXT "\r\nO xx yy - Output to port xx value yy" .TEXT "\r\nP xxxx - Program RAM at xxxx" .TEXT "\r\nR xxxx - Run code at xxxx" + .TEXT "\r\nS - Stop system (HALT)" + .TEXT "\r\nX - Exit monitor" .TEXT "$" ; #IF DSKYENABLE @@ -966,8 +999,6 @@ FRONTPANELLOOP1: JP Z,DOBOOT ; YES, JUMP JR FRONTPANELLOOP ; LOOP -EXIT: - RET ; ;__DOBOOT_____________________________________________________________________ ; @@ -1367,7 +1398,7 @@ DISPLAYBUF: .FILL 8,0 #ELSE ; DSKY_ENTRY: - CALL PANIC + JP EXIT ; #ENDIF ; @@ -1381,12 +1412,12 @@ MON_STACK .EQU $ .ECHO SLACK .ECHO " bytes.\n" ; -; DBGMON CURRENTLY OCCUPIES $F000-$FDFF BECAUSE THE -; HBIOS PROXY OCCUPIES $FE00-$FFFF. HOWEVER THE DBGMON +; DBGMON CURRENTLY OCCUPIES $F000 TO START OF HBX PROXY BECAUSE THE +; HBIOS PROXY OCCUPIES THE TOP OF COMMON RAM. HOWEVER THE DBGMON ; IMAGE MUST OCCUPY A FULL $1000 BYTES IN THE ROM. -; BELOW WE JUST PAD OUT THE IMAGE BY $200 SO IT +; BELOW WE JUST PAD OUT THE IMAGE SO IT ; OCCUPIES THE FULL $1000 BYTES IN ROM. ; - .FILL $200,$00 + .FILL HBX_SIZ ; PAD FOR HBX SIZE ; .END diff --git a/Source/HBIOS/diskdefs b/Source/HBIOS/diskdefs index 937bfcf2..db9ef4b2 100644 --- a/Source/HBIOS/diskdefs +++ b/Source/HBIOS/diskdefs @@ -297,121 +297,169 @@ diskdef wbw_rom1024 os 2.2 end -# UNA 512KB ROM (128KB reserved, 384KB ROM Disk) +# RomWBW 720K floppy media +diskdef wbw_fd720 + seclen 512 + tracks 160 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom512 +# RomWBW 1.44M floppy media +diskdef wbw_fd144 seclen 512 - tracks 12 - sectrk 64 + tracks 160 + sectrk 18 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# UNA 512KB ROM (128KB reserved, 896KB ROM Disk) +# RomWBW 360K floppy media +diskdef wbw_fd360 + seclen 512 + tracks 80 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom1024 +# RomWBW 1.20M floppy media +diskdef wbw_fd120 seclen 512 - tracks 28 - sectrk 64 + tracks 160 + sectrk 15 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# RomWBW 8MB Hard Disk, LU 0-3 -diskdef wbw_hd0 +# RomWBW 8320KB Hard Disk Slice (512 directory entry format) +# Legacy format, 512 dir entries, 16,630 sectors / slice +diskdef wbw_hd512 seclen 512 - tracks 65 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 1 + boottrk 16 os 2.2 end -diskdef wbw_hd1 +# First 4 slices of wbw_hd512 +diskdef wbw_hd512_0 seclen 512 - tracks 130 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 66 + boottrk 16 os 2.2 end -diskdef wbw_hd2 +diskdef wbw_hd512_1 seclen 512 - tracks 195 - sectrk 256 + tracks 2080 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 131 + boottrk 1056 os 2.2 end -diskdef wbw_hd3 +diskdef wbw_hd512_2 seclen 512 - tracks 260 - sectrk 256 + tracks 3120 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 196 + boottrk 2096 os 2.2 end -# RomWBW 720K floppy media -diskdef wbw_fd720 +diskdef wbw_hd512_3 seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 4160 + sectrk 16 + blocksize 4096 + maxdir 512 skew 0 - boottrk 4 + boottrk 3136 os 2.2 end -# RomWBW 1.44M floppy media -diskdef wbw_fd144 + +# RomWBW 8MB Hard Disk (1024 directory entry format) +# New format, 1024 dir entries, 16,384 sectors / slice +# Pure filesystem image, no MBR prefix +diskdef wbw_hd1024 seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 + tracks 1024 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 boottrk 2 os 2.2 end -# RomWBW 360K floppy media -diskdef wbw_fd360 +# First 4 slices of wbw_hd1024 +# Assumes 128KB prefix (256 sectors) +diskdef wbw_hd1024_0 seclen 512 - tracks 80 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 1040 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 18 os 2.2 end -# RomWBW 1.20M floppy media -diskdef wbw_fd120 +diskdef wbw_hd1024_1 seclen 512 - tracks 160 - sectrk 15 - blocksize 2048 - maxdir 256 + tracks 2064 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 1042 + os 2.2 +end + +diskdef wbw_hd1024_2 + seclen 512 + tracks 3112 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 2066 + os 2.2 +end + +diskdef wbw_hd1024_3 + seclen 512 + tracks 4136 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 3114 os 2.2 end diff --git a/Source/HBIOS/dsrtc.asm b/Source/HBIOS/dsrtc.asm index 5bcd596f..4384cce7 100644 --- a/Source/HBIOS/dsrtc.asm +++ b/Source/HBIOS/dsrtc.asm @@ -235,13 +235,27 @@ DSRTC_DISPATCH: JP Z,DSRTC_GETBLK ; GET NVRAM DATA BLOCK VALUES DEC A JP Z,DSRTC_SETBLK ; SET NVRAM DATA BLOCK VALUES - CALL PANIC + DEC A + JP Z,DSRTC_GETALM ; GET ALARM + DEC A + JP Z,DSRTC_SETALM ; SET ALARM + DEC A + JP Z,DSRTC_DEVICE ; REPORT RTC DEVICE INFO + CALL SYSCHK + LD A,ERR_NOFUNC + OR A + RET ; ; NVRAM FUNCTIONS ARE NOT AVAILABLE IN SIMULATOR ; DSRTC_GETBLK: DSRTC_SETBLK: - CALL PANIC +DSRTC_GETALM: +DSRTC_SETALM: + CALL SYSCHK + LD A,ERR_NOTIMPL + OR A + RET ; ; RTC GET TIME ; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR @@ -350,6 +364,16 @@ DSRTC_SETBYT: XOR A ; SIGNAL SUCCESS RET ; DONE ; +; REPORT RTC DEVICE INFO +; +DSRTC_DEVICE: + LD D,RTCDEV_DS ; D := DEVICE TYPE + LD E,0 ; E := PHYSICAL DEVICE NUMBER + LD H,DSRTCMODE ; H := MODE + LD L,DSRTC_IO ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; ; CONVERT DATA IN CLOCK BUFFER TO TIME BUFFER AT HL ; DSRTC_CLK2TIM: diff --git a/Source/HBIOS/duart.asm b/Source/HBIOS/duart.asm new file mode 100644 index 00000000..7b03fd93 --- /dev/null +++ b/Source/HBIOS/duart.asm @@ -0,0 +1,865 @@ +; +;================================================================================================== +; DUART DRIVER (SERIAL PORT) +;================================================================================================== +; +; SETUP PARAMETER WORD: +; +-------+---+-------------------+ +---+---+-----------+---+-------+ +; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 | +; +-------+---+---+---------------+ ----+---+-----------+---+-------+ +; F E D C B A 9 8 7 6 5 4 3 2 1 0 +; -- MSB (D REGISTER) -- -- LSB (E REGISTER) -- +; +; MODE REGISTER 1 +; +; D7 D6 D5 D4 D3 D2 D1 D0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | RXRTS | RXINT | EMODE | PARITY MODE | SEL | BITS/CHAR | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; RXRTS: AUTOMATIC CONTROL OF /RTS BY RECEIVER +; 0 = NO +; 1 = YES +; RXINT: RECEIVE INTERRUPT SELECT +; 0 = RXRDY +; 1 = FFULL +; EMODE: ERROR MODE +; 0 = BY CHARACTER +; 1 = BY BLOCK +; PARITY MODE: +; 00 = WITH PARITY +; 01 = FORCE PARITY +; 10 = NO PARITY +; 11 = MULTIDROP MODE +; SEL: PARITY TYPE +; 0 = EVEN / SPACE +; 1 = ODD / MARK +; BITS/CHAR: +; 00 = 5 +; 01 = 6 +; 10 = 7 +; 11 = 8 +; +; MODE REGISTER 2 +; +; D7 D6 D5 D4 D3 D2 D1 D0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | CHANNEL MODE | TXRTS | TXCTS | STOP BIT LENGTH | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; CHANNEL MODE: +; 00 = NORMAL +; 01 = AUTO-ECHO +; 10 = LOCAL LOOP +; 11 = REMOTE LOOP +; TXRTS: AUTOMATIC CONTROL OF /RTS BY TRANSMITTER +; 0 = NO +; 1 = YES +; TXCTS: AUTOMATIC CONTROL OF TRANSMITTER BY /CTS +; 0 = NO +; 1 = YES +; STOP BIT LENGTH: +; 0 = 9/16 +; 1 = 10/16 = 5/8 +; 2 = 11/16 +; 3 = 12/16 = 3/4 +; 4 = 13/16 +; 5 = 14/16 = 7/8 +; 6 = 15/16 +; 7 = 16/16 = 1 +; 8-F = LENGTHS OF 0-7 PLUS ONE +; IF BITS/CHAR = 5 THEN ADD AN ADDITIONAL HALF BIT +; +DUART_DEBUG .EQU FALSE +; +DUART_NONE .EQU 0 ; UNKNOWN OR NOT PRESETN +DUART_2681 .EQU 1 ; OLD '681 WITHOUT IVR/GPR +DUART_26C92 .EQU 2 ; '92 WITH MR0 +DUART_XR88C681 .EQU 3 ; EXAR/MAXLINEAR CHIP WITH Z-MODE +; +DUART_BAUD_INV .EQU $FF ; INVALID BAUD RATE +DUART_BAUD_ACR7 .EQU %10000000 ; ACR BIT 7 = 1 +DUART_BAUD_X1 .EQU %01000000 ; BRG EXTEND BIT = 1 ('681) +DUART_BAUD_EXT1 .EQU %00100000 ; EXTENDED TABLE 1 ('92) +DUART_BAUD_EXT2 .EQU %00010000 ; EXTENDED TABLE 2 ('92) +; +; PER CHANNEL REGISTERS (CHANNEL A AT OFFSET 0, CHANNEL B AT OFFSET 8) +; +DUART_MR .EQU $00 ; MODE REGISTER (R/W) +DUART_SR .EQU $01 ; STATUS REGISTER (READ) +DUART_CSR .EQU $01 ; CLOCK SELECT REGISTER (WRITE) +DUART_CR .EQU $02 ; COMMAND REGISTER (WRITE) +DUART_RX .EQU $03 ; RECEIVER HOLDING REGISTER (READ) +DUART_TX .EQU $03 ; TRANSMITTER HOLDING REGISTER (WRITE) +; +; PER CHIP REGISTERS +; +DUART_IPCR .EQU $04 ; INPUT PORT CHANGE REGISTER (READ) +DUART_ACR .EQU $04 ; AUXILLIARY CONTROL REGISTER (WRITE) +DUART_ISR .EQU $05 ; INTERRUPT STATUS REGISTER (READ) +DUART_IMR .EQU $05 ; INTERRUPT MASK REGISTER (WRITE) +DUART_CTU .EQU $06 ; COUNTER/TIMER UPPER BYTE REGISTER (R/W) +DUART_CTL .EQU $07 ; COUNTER/TIMER LOWER BYTE REGISTER (R/W) +DUART_GPR .EQU $0C ; GENERAL PURPOSE REGISTER (R/W) +DUART_IVR .EQU $0C ; INTERRUPT VECTOR REGISTER (R/W) +DUART_IPR .EQU $0D ; INPUT PORT REGISTER (READ) +DUART_OPCR .EQU $0D ; OUTPUT PORT CONFIGURATION REGISTER (WRITE) +DUART_STCR .EQU $0E ; START COUNTER/TIMER COMMAND (READ) +DUART_SOPR .EQU $0E ; SET OUTPUT PORT REGISTER (WRITE) +DUART_SPCR .EQU $0F ; STOP COUNTER/TIMER COMMAND (READ) +DUART_ROPR .EQU $0F ; RESET OUTPUT PORT REGISTER (WRITE) +; +; COMMAND REGISTER +; +DUART_CR_ENA_RX .EQU %00000100 ; ENABLE RECEIVER +DUART_CR_DIS_RX .EQU %00001000 ; DISABLE RECEIVER +DUART_CR_ENA_TX .EQU %00000001 ; ENABLE TRANSMITTER +DUART_CR_DIS_TX .EQU %00000010 ; DISABLE TRANSMITTER +DUART_CR_NOP .EQU $00 ; NULL COMMAND +DUART_CR_MR1 .EQU $10 ; RESET MR POINTER TO MR1 +DUART_CR_RESET_RX .EQU $20 ; RESET RECEIVER +DUART_CR_RESET_TX .EQU $30 ; RESET TRANSMITTER +DUART_CR_RESET_ERR .EQU $40 ; RESET ERROR STATUS +DUART_CR_RESET_BRK .EQU $50 ; RESET BREAK STATUS +DUART_CR_START_BRK .EQU $60 ; START BREAK +DUART_CR_STOP_BRK .EQU $70 ; STOP BREAK +DUART_CR_SET_RX_X .EQU $80 ; SET RECEIVER BRG EXTEND BIT (X=1) +DUART_CR_CLR_RX_X .EQU $90 ; CLEAR RECEIVER BRG EXTEND BIT (X=0) +DUART_CR_SET_TX_X .EQU $A0 ; SET TRANSMITTER BRG EXTEND BIT (X=1) +DUART_CR_CLR_TX_X .EQU $B0 ; CLEAR TRANSMITTER BRG EXTEND BIT (X=0) +DUART_CR_MR0 .EQU $B0 ; RESET MR POINTER TO MR0 (26C92 ONLY) +DUART_CR_STANDBY .EQU $C0 ; SET STANDBY MODE (CHANNEL A ONLY) +DUART_CR_RESET_IUS .EQU $C0 ; RESET IUS LATCH (CHANNEL B ONLY) +DUART_CR_ACTIVE .EQU $D0 ; SET ACTIVE MODE (CHANNEL A ONLY) +DUART_CR_ZMODE .EQU $D0 ; SET Z-MODE (CHANNEL B ONLY) +; +; DUART STATUS REGISTER +; +DUART_SR_RXRDY .EQU %00000001 ; RECEIVER READY +DUART_SR_RXFULL .EQU %00000010 ; RECEIVE FIFO FULL +DUART_SR_TXRDY .EQU %00000100 ; TRANSMITTER READY +DUART_SR_TXEMPTY .EQU %00001000 ; TRANSMITTER FIFO EMPTY +DUART_SR_OVERRUN .EQU %00010000 ; OVERRUN ERROR +DUART_SR_PARITY .EQU %00100000 ; PARITY ERROR +DUART_SR_FRAMING .EQU %01000000 ; FRAMING ERROR +DUART_SR_BREAK .EQU %10000000 ; RECEIVED BREAK +; +; DUART MODE REGISTER 0 +; +DUART_MR0_NORMAL .EQU %00000000 ; NORMAL BAUD RATE TABLE +DUART_MR0_EXT1 .EQU %00000001 ; EXTENDED BAUD RATE TABLE 1 +DUART_MR0_EXT2 .EQU %00000100 ; EXTENDED BAUD RATE TABLE 2 +; +; DUART MODE REGISTER 1 +; +DUART_MR1_RXRTS .EQU %10000000 ; RECEIVER CONTROLS RTS +DUART_MR1_PARNONE .EQU %00010000 ; NO PARITY +DUART_MR1_PARODD .EQU %00000100 ; ODD PARITY +DUART_MR1_PAREVEN .EQU %00000000 ; EVEN PARITY +DUART_MR1_PARMARK .EQU %00001100 ; MARK PARITY +DUART_MR1_PARSPACE .EQU %00001000 ; SPACE PARITY +; +; DUART MODE REGISTER 2 +; +DUART_MR2_TXCTS .EQU %00010000 ; CTS CONTROLS TRANSMITTER +DUART_MR2_STOP1 .EQU %00000111 ; 1 STOP BIT (1.5 IF 5 BITS/CHAR) +DUART_MR2_STOP2 .EQU %00001111 ; 2 STOP BITS (2.5 IF 5 BITS/CHAR) +; +; +#DEFINE DUART_INP(RID) CALL DUART_INP_IMP \ .DB RID +#DEFINE DUART_OUTP(RID) CALL DUART_OUTP_IMP \ .DB RID +; +; +; +DUART_PREINIT: +; +; SETUP THE DISPATCH TABLE ENTRIES +; + LD B,DUART_CFGCNT ; LOOP CONTROL + XOR A ; ZERO TO ACCUM + LD (DUART_DEV),A ; CURRENT DEVICE NUMBER + LD IY,DUART_CFG ; POINT TO START OF CFG TABLE +DUART_PREINIT0: + PUSH BC ; SAVE LOOP CONTROL + CALL DUART_DETECT ; DETERMINE DUART TYPE + POP BC ; RESTORE LOOP CONTROL + LD (IY + 1),A ; SAVE TYPE IN CONFIG TABLE + OR A ; SET FLAGS + JR Z,DUART_PREINIT1 ; SKIP IT IF NOTHING FOUND +; + PUSH BC ; SAVE LOOP CONTROL + PUSH IY + POP DE ; DE := UNIT INSTANCE TABLE ADDRESS + LD BC,DUART_FNTBL ; BC := FUNCTION TABLE ADDRESS + CALL NZ,CIO_ADDENT ; ADD ENTRY IF DUART FOUND, BC:DE + POP BC ; RESTORE LOOP CONTROL +; +DUART_PREINIT1: + LD DE,DUART_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,DE ; BUMP IY TO NEXT ENTRY + DJNZ DUART_PREINIT0 ; LOOP UNTIL DONE +; + LD B,DUART_CFGCNT ; LOOP CONTROL + LD IY,DUART_CFG ; POINT TO START OF CFG TABLE +DUART_PREINIT2: + PUSH BC ; SAVE LOOP CONTROL + CALL DUART_INITUNIT ; INITIALIZE UNIT + POP BC ; RESTORE LOOP CONTROL + LD DE,DUART_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,DE ; BUMP IY TO NEXT ENTRY + DJNZ DUART_PREINIT2 ; LOOP UNTIL DONE +; + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; DUART INITIALIZATION ROUTINE +; +DUART_INITUNIT: + ; CHECK IF PORT IS PRESENT + LD A,(IY + 1) ; GET TYPE FROM CONFIG TABLE + OR A ; SET FLAGS + RET Z ; ABORT IF NOTHING THERE + + ; UPDATE WORKING DUART DEVICE NUM + LD HL,DUART_DEV ; POINT TO CURRENT DUART DEVICE NUM + LD A,(HL) ; PUT IN ACCUM + INC (HL) ; INCREMENT IT (FOR NEXT LOOP) + LD (IY),A ; UDPATE UNIT NUM + + ; SET DEFAULT CONFIG + LD DE,-1 ; LEAVE CONFIG ALONE + JP DUART_INITDEV ; IMPLEMENT IT AND RETURN +; +; +; +DUART_INIT: + LD B,DUART_CFGCNT ; COUNT OF POSSIBLE DUART UNITS + LD IY,DUART_CFG ; POINT TO START OF CFG TABLE +DUART_INIT1: + PUSH BC ; SAVE LOOP CONTROL + LD A,(IY + 1) ; GET DUART TYPE + OR A ; SET FLAGS + CALL NZ,DUART_PRTCFG ; PRINT IF NOT ZERO + + POP BC ; RESTORE LOOP CONTROL + LD DE,DUART_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,DE ; BUMP IY TO NEXT ENTRY + DJNZ DUART_INIT1 ; LOOP TILL DONE +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; DRIVER FUNCTION TABLE +; +DUART_FNTBL: + .DW DUART_IN + .DW DUART_OUT + .DW DUART_IST + .DW DUART_OST + .DW DUART_INITDEV + .DW DUART_QUERY + .DW DUART_DEVICE +#IF (($ - DUART_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID DUART FUNCTION TABLE ***\n" +#ENDIF +; +; +; +DUART_IN: + CALL DUART_IST ; RECEIVED CHAR READY? + JR Z,DUART_IN ; LOOP IF NOT + DUART_INP(DUART_RX) ; GET CHAR READ IN A + LD E,A ; CHAR READ TO E + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +; +; +DUART_OUT: + CALL DUART_OST ; READY FOR CHAR? + JR Z,DUART_OUT ; LOOP IF NOT + LD A,E ; GET CHAR TO SEND IN A + DUART_OUTP(DUART_TX) ; SEND CHAR FROM A + XOR A ; SIGNAL SUCCESS + RET +; +; +; +DUART_IST: + DUART_INP(DUART_SR) ; GET CHANNEL STATUS REGISTER IN A + AND DUART_SR_RXRDY ; ISOLATE RXRDY BIT + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + XOR A ; ZERO ACCUM + INC A ; ACCUM := 1 TO SIGNAL 1 CHAR WAITING + RET ; DONE +; +; +; +DUART_OST: + DUART_INP(DUART_SR) ; GET CHANNEL STATUS REGISTER IN A + AND DUART_SR_TXRDY ; ISOLATE TXRDY BIT + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + XOR A ; ZERO ACCUM + INC A ; ACCUM := 1 TO SIGNAL 1 BUFFER POSITION + RET ; DONE +; +; +; +DUART_INITDEV: + ; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT) + LD A,D ; TEST DE FOR + AND E ; ... VALUE OF -1 + INC A ; ... SO Z SET IF -1 + JR NZ,DUART_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG +; + ; LOAD EXISTING CONFIG TO REINIT + LD E,(IY + 8) ; LOW BYTE + LD D,(IY + 9) ; HIGH BYTE +; +DUART_INITDEV1: + ; GET CLOCK SELECT FROM TABLE + LD HL,DUART_BAUDTBL_681 ; GET START OF XR88C681 TABLE IN HL + LD A,(IY + 1) ; GET DUART TYPE + CP DUART_26C92 ; IS IT A 26C92? + JR NZ,DUART_INITDEV1A ; NO, SKIP NEXT INSTRUCTION + LD HL,DUART_BAUDTBL_92 ; GET START OF SC26C92 TABLE IN HL +; +DUART_INITDEV1A: + LD A,D ; GET CONFIG MSB + AND $1F ; ISOLATE ENCODED BAUD RATE + CALL ADDHLA ; HL -> ENTRY + LD A,(HL) ; A = ENTRY + INC A ; A = $FF? + JP Z,DUART_INITDEVZ ; INVALID RATE, ERROR OUT + DEC A ; GET ORIGINAL VALUE BACK +; + ; GOT A VALID RATE, COMMIT NEW CONFIG + LD (IY + 8),E ; SAVE LOW WORD + LD (IY + 9),D ; SAVE HI WORD +; + ; START OF ACTUAL DUART CHANNEL CONFIGURATION + LD L,A ; SAVE BAUD TABLE ENTRY IN L + LD A,DUART_CR_DIS_RX | DUART_CR_DIS_TX + DUART_OUTP(DUART_CR) ; DISABLE RECEIVER AND TRANSMITTER + LD A,DUART_CR_RESET_RX + DUART_OUTP(DUART_CR) ; RESET RECEIVER + LD A,DUART_CR_RESET_TX + DUART_OUTP(DUART_CR) ; RESET TRANSMITTER + LD A,DUART_CR_RESET_ERR + DUART_OUTP(DUART_CR) ; RESET ERROR STATUS + LD A,(IY + 1) ; GET DUART TYPE + CP DUART_26C92 ; IS IT A 26C92? + JR Z,DUART_INITDEV1B ; YES + CALL DUART_SETBAUD_681 ; NO, CALL '681 BRG SETUP + JR DUART_INITDEV2 +; +DUART_INITDEV1B: + CALL DUART_SETBAUD_92 ; CALL '92 BRG SETUP +; +DUART_INITDEV2: +; + ; SET PARITY AND WORD SIZE + LD A,DUART_CR_MR1 + DUART_OUTP(DUART_CR) ; SET MR POINTER TO MR1 + LD A,E ; GET LOW WORD OF CONFIG IN A + AND %00111000 ; KEEP ONLY PARITY BITS + RRA + RRA + RRA ; SHIFT PARITY BITS INTO AN INDEX + LD HL,DUART_PARTBL ; GET START OF TABLE IN HL + CALL ADDHLA ; HL -> ENTRY + LD B,(HL) ; BUILD MR1 IN B + LD A,E ; GET LOW WORD OF CONFIG IN A + AND %00000011 ; WORD LENGTH BITS ARE THE SAME + OR B ; MERGE PARITY BITS + OR DUART_MR1_RXRTS ; ALWAYS ENABLE RECEIVER CONTROL OF RTS + DUART_OUTP(DUART_MR) ; WRITE MR1 (AND SET MR POINTER TO MR2) +; + ; SET STOP BITS + LD A,E ; GET LOW WORD OF CONFIG IN A + LD B,DUART_MR2_STOP1 ; BUILD MR2 IN B + AND %00000100 ; KEEP ONLY STOP BITS + JR Z,DUART_INITDEV4 ; 1 STOP BIT + LD B,DUART_MR2_STOP2 ; 2 STOP BITS, REPLACE B +; +DUART_INITDEV4: + LD A,B ; GET MR2 IN A + ;OR DUART_MR2_TXCTS ; ALWAYS ENABLE CTS CONTROL OF TRANSMITTER + DUART_OUTP(DUART_MR) ; WRITE MR2 +; + ; RE-ENABLE RECEIVER AND TRANSMITTER + LD A,DUART_CR_ENA_RX | DUART_CR_ENA_TX + DUART_OUTP(DUART_CR) ; ENABLE RECEIVER AND TRANSMITTER +; + ; EXPLICITLY ASSERT RTS (SEEMS TO BE REQUIRED FOR SOME CHIPS TO DO AUTO-RTS) + LD L,%00000001 ; RTS FOR CHANNEL A IS IN BIT 0 + LD A,(IY) ; GET UNIT NUMBER IN A + AND L ; MASK ALL BUT CHANNEL + JR Z,DUART_INITDEV5 ; ZERO INDICATES CHANNEL A + SLA L ; MOVE INTO BIT 1, RTS FOR CHANNEL B +; +DUART_INITDEV5: + LD A,(IY + 2) ; GET BASE ADDRESS OF CHIP + ADD A,DUART_SOPR ; SET OUTPUT BITS + LD C,A ; GET PORT IN C + OUT (C),L ; OUTPUT PORT IS INVERTED BUT SO IS RTS +; + XOR A ; SIGNAL SUCCESS + RET +; +DUART_INITDEVZ: +; + ; INVALID BAUD RATE + DEC A ; A WAS $00, GET BACK $FF + RET ; RETURN ERROR STATUS +; +; INITIALIZE BRG FOR '681 DUART +; +DUART_SETBAUD_681: + ; SET ACR + LD C,(IY + 6) ; GET SHADOW ACR FOR THIS CHIP + LD B,(IY + 7) ; BC IS POINTER + LD A,(BC) ; GET SHADOW ACR IN A + AND %01111111 ; MASK OUT BIT 7 + LD H,A ; SAVE IT IN H + LD A,L ; TABLE ENTRY IS IN L, GET IT IN A + AND DUART_BAUD_ACR7 ; SEE IF ACR[7] SHOULD BE SET (BIT MASK SHOULD ACTUALLY _BE_ BIT 7) + OR H ; MERGE IN REST OF ACR + LD H,A ; SAVE IT IN H + LD A,(IY + 2) ; GET CHIP BASE IN A + ADD A,DUART_ACR ; ADD OFFSET OF ACR + LD C,A ; C = ACR PORT + ; YES, THIS OVERWRITES ACR[7] REGARDLESS OF THE OTHER CHANNEL, + ; BUT CURRENTLY THE TABLE IS SET SO EVERY VALID RATE HAS ACR[7] SET + OUT (C),H ; WRITE VALUE + ; SELECT PER-CHANNEL EXTENDED TABLE + LD A,L ; CALLED WITH TABLE ENTRY IN L, MOVE IT TO A + AND DUART_BAUD_X1 ; SEE IF SELECT EXTEND BIT SHOULD BE SET + JR Z,DUART_SETBAUD_681A ; NO, CLEAR IT + LD A,DUART_CR_SET_RX_X ; YES, SET EXTEND BIT + DUART_OUTP(DUART_CR) ; SET FOR RECEIVER + LD A,DUART_CR_SET_TX_X + DUART_OUTP(DUART_CR) ; SET FOR TRANSMITTER + JR DUART_SETBAUD_681B +; +DUART_SETBAUD_681A: + ; CLEAR EXTEND BIT + LD A,DUART_CR_CLR_RX_X + DUART_OUTP(DUART_CR) ; CLEAR FOR RECEIVER + LD A,DUART_CR_CLR_TX_X + DUART_OUTP(DUART_CR) ; CLEAR FOR TRANSMITTER +; +DUART_SETBAUD_681B: + ; SET BRG CLOCK SELECT + LD A,L ; GET BAUD TABLE ENTRY IN A + AND $0F ; GET CLOCK SELECT BITS + LD L,A ; SAVE IT IN L + RLA + RLA + RLA + RLA ; MOVE IT INTO THE HIGH NIBBLE + OR L ; AND MERGE BACK IN LOW NIBBLE + DUART_OUTP(DUART_CSR) ; SET CLOCK SELECT + RET +; +DUART_BAUDTBL_681: + ; ASSUME XR88C681 RUNS AT 3.6864MHZ + .DB %0000 | DUART_BAUD_X1 ; 75 + .DB %0011 | DUART_BAUD_X1 ; 150 + .DB %0100 ; 300 + .DB %0101 ; 600 + .DB %0110 ; 1200 + .DB %1000 ; 2400 + .DB %1001 ; 4800 + .DB %1011 ; 9600 + .DB %1100 | DUART_BAUD_X1 ; 19200 + .DB %1100 ; 38400 + .DB DUART_BAUD_INV ; 76800 + .DB DUART_BAUD_INV ; 153600 + .DB DUART_BAUD_INV ; 307200 + .DB DUART_BAUD_INV ; 614400 + .DB DUART_BAUD_INV ; 1228800 + .DB DUART_BAUD_INV ; 2457600 + .DB DUART_BAUD_INV ; 225 + .DB DUART_BAUD_INV ; 450 + .DB DUART_BAUD_INV ; 900 + .DB %1010 | DUART_BAUD_X1 ; 1800 + .DB %0100 | DUART_BAUD_X1 ; 3600 + .DB %1010 ; 7200 + .DB %0101 | DUART_BAUD_X1 ; 14400 + .DB %0110 | DUART_BAUD_X1 ; 28800 + .DB %0111 | DUART_BAUD_X1 ; 57600 + .DB %1000 | DUART_BAUD_X1 ; 115200 + .DB DUART_BAUD_INV ; 230400 + .DB DUART_BAUD_INV ; 460800 + .DB DUART_BAUD_INV ; 921600 + .DB DUART_BAUD_INV ; 1843200 + .DB DUART_BAUD_INV ; 3686400 + .DB DUART_BAUD_INV ; 7372800 +; +; INITIALIZE BRG FOR '92 DUART +; +DUART_SETBAUD_92: + ; SET ACR + LD C,(IY + 6) ; GET SHADOW ACR FOR THIS CHIP + LD B,(IY + 7) ; BC IS POINTER + LD A,(BC) ; GET SHADOW ACR IN A + AND %01111111 ; MASK OUT BIT 7 + LD H,A ; SAVE IT IN H + LD A,L ; TABLE ENTRY IS IN L, GET IT IN A + AND DUART_BAUD_ACR7 ; SEE IF ACR[7] SHOULD BE SET (BIT MASK SHOULD ACTUALLY _BE_ BIT 7) + OR H ; MERGE IN REST OF ACR + LD H,A ; SAVE IT IN H + LD A,(IY + 2) ; GET CHIP BASE IN A + ADD A,DUART_ACR ; ADD OFFSET OF ACR + LD C,A ; C = ACR PORT + ; YES, THIS OVERWRITES ACR[7] REGARDLESS OF THE OTHER CHANNEL, + ; BUT CURRENTLY THE TABLE IS SET SO EVERY VALID RATE HAS ACR[7] SET + OUT (C),H ; WRITE VALUE + ; SELECT NORMAL OR EXTENDED BAUD RATE TABLES + LD H,DUART_MR0_NORMAL ; ASSUME NORMAL + LD A,L ; GET TABLE ENTRY IN A AGAIN + AND DUART_BAUD_EXT1 ; SHOULD EXT1 BE SET? + JR Z,DUART_SETBAUD_92A ; NO, CHECK NEXT VALUE + LD H,DUART_MR0_EXT1 ; YES, SET IT + JR DUART_SETBAUD_92C +; +DUART_SETBAUD_92A: + LD A,L ; GET TABLE ENTRY IN A ONCE MORE + AND DUART_BAUD_EXT2 ; SHOULD EXT2 BE SET? + JR Z,DUART_SETBAUD_92C ; NO, CONTINUE + LD H,DUART_MR0_EXT2 ; YES, SET IT +; +DUART_SETBAUD_92C: + ; H NOW CONTAINS MR0 + LD A,(IY + 2) ; GET CHIP BASE IN A + ADD A,DUART_CR ; WE WANT TO WRITE THE COMMAND REGISTER OF CHANNEL A, EVEN IF WE'RE CHANNEL B + LD C,A ; C = CRA + LD A,DUART_CR_MR0 ; RESET MR POINTER TO MR0 + OUT (C),A ; WRITE COMMAND + LD A,(IY + 2) ; GET CHIP BASE IN A + ADD A,DUART_MR ; NOW WE WANT TO WRITE TO MR0 OF CHANNEL A + LD C,A ; C = MRA + ; AS WITH ACR[7] THE TABLE IS SET SO EVERY VALID RATE IS FROM + ; THE SAME TABLE + OUT (C),H + ; SET BRG CLOCK SELECT + LD A,L ; GET BAUD TABLE ENTRY IN A YET AGAIN + AND $0F ; GET CLOCK SELECT BITS + LD L,A ; SAVE IT IN L + RLA + RLA + RLA + RLA ; MOVE IT INTO THE HIGH NIBBLE + OR L ; AND MERGE BACK IN LOW NIBBLE + DUART_OUTP(DUART_CSR) ; SET CLOCK SELECT OF CURRENT CHANNEL + RET +; +DUART_BAUDTBL_92: + ; ASSUME SC26C92 RUNS AT 7.3728MHZ + .DB DUART_BAUD_INV ; 75 + .DB DUART_BAUD_INV ; 150 + .DB DUART_BAUD_INV ; 300 + .DB DUART_BAUD_INV ; 600 + .DB DUART_BAUD_INV ; 1200 + .DB DUART_BAUD_INV ; 2400 + .DB DUART_BAUD_INV ; 4800 + .DB %1001 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 9600 + .DB %1011 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 19200 + .DB %1100 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 38400 + .DB DUART_BAUD_INV ; 76800 + .DB DUART_BAUD_INV ; 153600 + .DB DUART_BAUD_INV ; 307200 + .DB DUART_BAUD_INV ; 614400 + .DB DUART_BAUD_INV ; 1228800 + .DB DUART_BAUD_INV ; 2457600 + .DB DUART_BAUD_INV ; 225 + .DB DUART_BAUD_INV ; 450 + .DB DUART_BAUD_INV ; 900 + .DB DUART_BAUD_INV ; 1800 + .DB DUART_BAUD_INV ; 3600 + .DB DUART_BAUD_INV ; 7200 + .DB %0000 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 14400 + .DB %0011 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 28800 + .DB %0100 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 57600 + .DB %0101 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 115200 + .DB %0110 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 230400 + .DB DUART_BAUD_INV ; 460800 + .DB DUART_BAUD_INV ; 921600 + .DB DUART_BAUD_INV ; 1843200 + .DB DUART_BAUD_INV ; 3686400 + .DB DUART_BAUD_INV ; 7372800 +; +DUART_PARTBL: + .DB DUART_MR1_PARNONE ; 0 = NO PARITY (ALSO ALL EVEN ENTRIES) + .DB DUART_MR1_PARODD ; 1 = ODD PARITY + .DB DUART_MR1_PARNONE + .DB DUART_MR1_PAREVEN ; 3 = EVEN PARITY + .DB DUART_MR1_PARNONE + .DB DUART_MR1_PARMARK ; 5 = MARK PARITY + .DB DUART_MR1_PARNONE + .DB DUART_MR1_PARSPACE ; 7 = SPACE PARITY +; +; +; +DUART_QUERY: + LD E,(IY + 8) ; FIRST CONFIG BYTE TO E + LD D,(IY + 9) ; SECOND CONFIG BYTE TO D + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; +; +DUART_DEVICE: + LD D,CIODEV_DUART ; D := DEVICE TYPE + LD E,(IY) ; E := PHYSICAL UNIT + LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+3) ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; +; DUART DETECTION ROUTINE +; +DUART_DETECT: +; + ; FIRST SEE IF IT LOOKS LIKE A 16X50-STYLE UART + LD A,(IY + 2) ; GET BASE PORT OF CHIP + ADD A,4 ; BASE + 4 = ACR (DUART), MCR (1ST 16X50) + LD H,A ; H := ACR/MCR PORT ADDRESS + ADD A,2 ; BASE + 6 = CTU (DUART), MSR (1ST 16X50) + LD B,A ; B := CTU/MSR PORT ADDRESS + INC A ; BASE + 7 = CTL (DUART), SCR (1ST 16X50) + LD D,A ; D := CTL/SCR PORT ADDRESS + ADD A,7 ; BASE + 14 = STCR (DUART), MSR (2ND 16X50) + LD E,A ; E := STCR/MSR PORT ADDRESS + INC A ; BASE + 15 = SPCR (DUART), SCR (2ND 16X50) + LD C,A ; SPCR + IN A,(C) ; STOP COUNTER/TIMER, JUST IN CASE + LD C,H ; ACR/MCR + IN L,(C) ; GET ORIGINAL VALUE (ACTUALLY IPCR ON DUART) IN L + LD A,$30 ; ENABLE A SOURCE FOR THE COUNTER/TIMER + OUT (C),A ; WRITE TO ACR/MCR + LD A,$A5 ; TEST VALUE + LD C,B ; CTU + OUT (C),A ; WRITE TEST VALUE TO CTU + LD A,$FF ; LARGE VALUE TO PREVENT CTL FROM ROLLING OVER WHILE WE TEST + LD C,D ; CTL + OUT (C),A ; WRITE LARGE VALUE TO CTL + LD C,E ; STCR + IN A,(C) ; START COUNTER/TIMER (LATCH CTU, CTL) + INC C ; C := SPCR + IN A,(C) ; STOP COUNTER/TIMER + LD C,H ; ACR/MCR + OUT (C),L ; WRITE ORIGINAL VALUE OF MCR (ACR GETS SET ON DUART LATER) + LD C,B ; CTU + IN A,(C) ; READ BACK TEST VALUE + CP $A5 ; CHECK FOR TEST VALUE + JR NZ,DUART_DETECT_NONE ; NO, PROBABLY NOT A DUART + IN A,(C) ; CHECK TEST VALUE AGAIN, + CP $A5 ; ... IN RARE CASE DELTAS IN MSR WERE SET TO OUR TEST + JR NZ,DUART_DETECT_NONE ; ALMOST CERTAINLY NOT A DUART + ; SEE IF MR1 AND MR2 ARE DISTINCT + LD A,DUART_CR_MR1 ; SET MR POINTER TO MR1 + DUART_OUTP(DUART_CR) ; SEND COMMAND + LD A,1 ; WRITE TEST VALUE TO MR1 + DUART_OUTP(DUART_MR) ; WRITE MR1 AND SET POINTER TO MR2 + XOR A ; WRITE 0 TO MR2 + DUART_OUTP(DUART_MR) ; WRITE MR2 AND KEEP POINTER TO MR2 + LD A,DUART_CR_MR1 ; SET MR POINTER TO MR1 (AGAIN) + DUART_OUTP(DUART_CR) ; SEND COMMAND + DUART_INP(DUART_MR) ; GET VALUE OF MR1 IN A + CP 1 ; CHECK FOR TEST VALUE + JR NZ,DUART_DETECT_NONE ; NOPE, UNKNOWN DEVICE OR NOT PRESENT +; + ; TEST FOR FUNCTIONAL GENERAL PURPOSE REG, IF NOT, WE HAVE A 2681 + LD A,$5A ; LOAD TEST VALUE + DUART_OUTP(DUART_GPR) ; PUT IT IN GENERAL PURPOSE REGISTER + DUART_INP(DUART_GPR) ; READ IT BACK + CP $5A ; CHECK IT + JR NZ,DUART_DETECT_2681 ; OLD CHIP +; + ; TEST FOR MR0 REGISTER, IN WHICH CASE WE HAVE A 26C92 OF SOME SORT + LD A,DUART_CR_MR0 ; SET MR POINTER TO MR0 + DUART_OUTP(DUART_CR) ; THIS IS HARMLESS ON OTHER CHIPS + LD A,1 ; WRITE TEST VALUE TO MR0 + DUART_OUTP(DUART_MR) ; WRITE TO MR0 ON 26C92, MR2 STILL SET ON OTHERS + LD A,DUART_CR_MR1 ; SET MR POINTER TO MR1 + DUART_OUTP(DUART_CR) ; THIS WORKS ON ALL CHIPS + XOR A ; WRITE 0 TO MR1 + DUART_OUTP(DUART_MR) ; WRITE MR1 AND SET POINTER TO MR2 + XOR A ; ALSO WRITE 0 TO MR2 + DUART_OUTP(DUART_MR) ; WRITE MR2 AND KEEP POINTER TO MR2 + LD A,DUART_CR_MR0 ; SET POINTER TO MR0 + DUART_OUTP(DUART_CR) ; POINTER IS STILL MR2 ON OTHER CHIPS + DUART_INP(DUART_MR) ; GET VALUE OF MR0 IN A + AND 1 ; MASK TEST VALUE IN BIT 1 + JR NZ,DUART_DETECT_26C92 ; IF IT'S SET, THIS MUST BE A '92 WITH MR0 + + JR DUART_DETECT_XR88C681 ; ASSUME WE HAVE A FANCY EXAR CHIP +; +DUART_DETECT_NONE: + LD A,DUART_NONE + RET +; +DUART_DETECT_2681: + LD A,DUART_2681 + RET +; +DUART_DETECT_26C92: + LD A,DUART_26C92 + RET +; +DUART_DETECT_XR88C681 + LD A,DUART_XR88C681 + RET +; +; +; +DUART_PRTCFG: + ; ANNOUNCE PORT + CALL NEWLINE ; FORMATTING + PRTS("DUART$") ; FORMATTING + LD A,(IY) ; DEVICE NUM + CALL PRTDECB ; PRINT DEVICE NUM + PRTS(": IO=0x$") ; FORMATTING + LD A,(IY + 3) ; GET CHANNEL BASE PORT + CALL PRTHEXBYTE ; PRINT BASE PORT + + ; PRINT THE DUART TYPE + CALL PC_SPACE ; FORMATTING + LD A,(IY + 1) ; GET DUART TYPE BYTE + RLCA ; MAKE IT A WORD OFFSET + LD HL,DUART_TYPE_MAP ; POINT HL TO TYPE MAP TABLE + CALL ADDHLA ; HL := ENTRY + LD E,(HL) ; DEREFERENCE + INC HL ; ... + LD D,(HL) ; ... TO GET STRING POINTER + CALL WRITESTR ; PRINT IT +; + ; ALL DONE IF NO DUART WAS DETECTED + LD A,(IY + 1) ; GET DUART TYPE BYTE + OR A ; SET FLAGS + RET Z ; IF ZERO, NOT PRESENT +; + PRTS(" MODE=$") ; FORMATTING + LD E,(IY + 8) ; LOAD CONFIG + LD D,(IY + 9) ; ... WORD TO DE + CALL PS_PRTSC0 ; PRINT CONFIG +; + XOR A + RET +; +; ROUTINES TO READ/WRITE PORTS INDIRECTLY +; +; READ VALUE OF DUART PORT ON TOS INTO REGISTER A +; +DUART_INP_IMP: + EX (SP),HL ; SWAP HL AND TOS + PUSH BC ; PRESERVE BC + LD A,(IY + 3) ; GET DUART IO BASE PORT + OR (HL) ; OR IN REGISTER ID BITS + LD C,A ; C := PORT + IN A,(C) ; READ PORT INTO A + POP BC ; RESTORE BC + INC HL ; BUMP HL PAST REG ID PARM + EX (SP),HL ; SWAP BACK HL AND TOS + RET +; +; WRITE VALUE IN REGISTER A TO DUART PORT ON TOS +; +DUART_OUTP_IMP: + EX (SP),HL ; SWAP HL AND TOS + PUSH BC ; PRESERVE BC + LD B,A ; PUT VALUE TO WRITE IN B + LD A,(IY + 3) ; GET DUART IO BASE PORT + OR (HL) ; OR IN REGISTER ID BITS + LD C,A ; C := PORT + OUT (C),B ; WRITE VALUE TO PORT + POP BC ; RESTORE BC + INC HL ; BUMP HL PAST REG ID PARM + EX (SP),HL ; SWAP BACK HL AND TOS + RET +; +; +; +DUART_TYPE_MAP: + .DW DUART_STR_NONE + .DW DUART_STR_2681 + .DW DUART_STR_26C92 + .DW DUART_STR_XR88C681 + +DUART_STR_NONE .DB "$" +DUART_STR_2681 .DB "2681$" +DUART_STR_26C92 .DB "26C92$" +DUART_STR_XR88C681 .DB "XR88C681$" +; +; WORKING VARIABLES +; +DUART_DEV .DB 0 ; DEVICE NUM USED DURING INIT +; +; PER-CHIP VARIABLES +; +DUART0_ACR .DB 0 ; SHADOW ACR (DUART 0) +; +#IF (DUARTCNT >= 2) +; +DUART1_ACR .DB 0 ; SHADOW ACR (DUART 1) +; +#ENDIF +; +; DUART PORT TABLE +; +DUART_CFG: +; +DUART0A_CFG: + ; 1ST DUART MODULE CHANNEL A + .DB 0 ; IY DEVICE NUMBER (SET DURING INIT) + .DB 0 ; IY+1 DUART TYPE (SET DURING INIT) + .DB DUART0BASE ; IY+2 BASE PORT (CHIP) + .DB DUART0BASE + $00 ; IY+3 BASE PORT (CHANNEL) + .DW DUART0B_CFG ; IY+4 POINTER TO OTHER CHANNEL + .DW DUART0_ACR ; IY+6 POINTER TO SHADOW ACR FOR THIS CHIP + .DW DUART0ACFG ; IY+8 LINE CONFIGURATION + .DB 1 ; IY+10 MULTIPLIER WRT 3.6864MHZ CLOCK +; +DUART_CFGSIZ .EQU $ - DUART_CFG ; SIZE OF ONE CFG TABLE ENTRY +; +DUART0B_CFG: + ; 1ST DUART MODULE CHANNEL B + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; DUART TYPE (SET DURING INIT) + .DB DUART0BASE ; BASE PORT (CHIP) + .DB DUART0BASE + $08 ; BASE PORT (CHANNEL) + .DW DUART0A_CFG ; POINTER TO OTHER CHANNEL + .DW DUART0_ACR ; POINTER TO SHADOW ACR FOR THIS CHIP + .DW DUART0BCFG ; LINE CONFIGURATION + .DB 1 ; MULTIPLIER WRT 3.6864MHZ CLOCK +; +#IF (DUARTCNT >= 2) +; +DUART1A_CFG: + ; 2ND DUART MODULE CHANNEL A + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; DUART TYPE (SET DURING INIT) + .DB DUART1BASE ; BASE PORT (CHIP) + .DB DUART1BASE + $00 ; BASE PORT (CHANNEL) + .DW DUART1B_CFG ; POINTER TO OTHER CHANNEL + .DW DUART1_ACR ; POINTER TO SHADOW ACR FOR THIS CHIP + .DW DUART1ACFG ; LINE CONFIGURATION + .DB 1 ; MULTIPLIER WRT 3.6864MHZ CLOCK +; +DUART1B_CFG: + ; 2ND DUART MODULE CHANNEL B + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; DUART TYPE (SET DURING INIT) + .DB DUART1BASE ; BASE PORT (CHIP) + .DB DUART1BASE + $08 ; BASE PORT (CHANNEL) + .DW DUART1A_CFG ; POINTER TO OTHER CHANNEL + .DW DUART1_ACR ; POINTER TO SHADOW ACR FOR THIS CHIP + .DW DUART1BCFG ; LINE CONFIGURATION + .DB 1 ; MULTIPLIER WRT 3.6864MHZ CLOCK +; +#ENDIF +; +DUART_CFGCNT .EQU ($ - DUART_CFG) / DUART_CFGSIZ diff --git a/Source/HBIOS/eastaegg.asm b/Source/HBIOS/eastaegg.asm index 35c4c982..7d291165 100644 --- a/Source/HBIOS/eastaegg.asm +++ b/Source/HBIOS/eastaegg.asm @@ -179,10 +179,15 @@ waitch LD B,BF_CIOIN ; HBIOS FUNC: INPUT CHAR RST 08 ; DO IT - ; RETURN TO THE LOADER - LD A,BID_BOOT ; BOOT BANK - LD HL,0 ; ADDRESS ZERO - CALL HB_BNKCALL ; DOES NOT RETURN + ;; RETURN TO THE LOADER + ;LD A,BID_BOOT ; BOOT BANK + ;LD HL,0 ; ADDRESS ZERO + ;CALL HB_BNKCALL ; DOES NOT RETURN + + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_WARM ; WARM START + CALL $FFF0 ; CALL HBIOS + HALT #ENDIF #IF (BIOS == BIOS_UNA) diff --git a/Source/HBIOS/fd.asm b/Source/HBIOS/fd.asm index df2673be..7bf477ba 100644 --- a/Source/HBIOS/fd.asm +++ b/Source/HBIOS/fd.asm @@ -61,6 +61,13 @@ FDC_DOR .EQU FDC_BASE + $02 ; DIGITAL OUTPUT REGISTER FDC_DCR .EQU FDC_BASE + $03 ; CONFIGURATION CONTROL REGISTER FDC_TC .EQU FDC_BASE + $02 ; TERMINAL COUNT (W/ DACK) #ENDIF +#IF (FDMODE == FDMODE_EPFDC) +FDC_MSR .EQU $48 ; 8272 MAIN STATUS REGISTER +FDC_DATA .EQU $49 ; 8272 DATA PORT +FDC_DOR .EQU $4A ; DIGITAL OUTPUT REGISTER +FDC_DCR .EQU $4B ; CONFIGURATION CONTROL REGISTER +FDC_TC .EQU $4C ; TERMINAL COUNT (W/ DACK) +#ENDIF ; ; DISK OPERATIONS ; @@ -94,7 +101,7 @@ FRC_TOSEEKWT .EQU -15H ; EB ; ; FD DEVICE CONFIGURATION ; -FD_DEVCNT .EQU 2 ; 2 DEVICES SUPPORTED +FD_DEVCNT .EQU FDCNT ; 2 DEVICES SUPPORTED FD_CFGSIZ .EQU 8 ; SIZE OF CFG TBL ENTRIES ; ; PER DEVICE DATA OFFSETS @@ -399,7 +406,7 @@ DOR_INIT .EQU 11100000B ; INITIAL DEFAULT LATCH VALUE ; ; *** DIDE/N8/ZETA V2 *** ; -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO)) +#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO) | (FDMODE == FDMODE_EPFDC)) DOR_INIT .EQU 00001100B ; SOFT RESET INACTIVE, DMA ENABLED DOR_BR250 .EQU DOR_INIT DOR_BR500 .EQU DOR_INIT @@ -476,7 +483,10 @@ FD_FNTBL: FD_VERIFY: FD_FORMAT: FD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL SYSCHK ; INVALID SUB-FUNCTION + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -498,6 +508,8 @@ FD_DEVICE: #IF (FDMEDIA == FDM111) LD C,%10010100 ; 8" DS/DD #ENDIF + LD H,FDMODE ; H := MODE + LD L,FDC_MSR ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -548,7 +560,8 @@ FD_MEDIARETRY: ;LD (HL),0 ; SET TO NO MEDIA LD (IY+FD_MEDTYP),0 ; SET DRIVE = NO MEDIA LD E,0 - OR $FF ; SIGNAL ERROR + LD A,ERR_NOMEDIA ; SIGNAL ERROR + OR A ; SET FLAGS RET FD_TESTMEDIA: @@ -638,7 +651,9 @@ FD_INIT: PRTS("FD: IO=0x$") LD A,FDC_MSR CALL PRTHEXBYTE - PRTS(" UNITS=2$") + PRTS(" UNITS=$") + LD A, FD_DEVCNT + '0' + CALL COUT ; ; SETUP THE DISPATCH TABLE ENTRIES ; @@ -775,7 +790,7 @@ FD_FDCRESET: LD (FCD_FDCRDY),A ; MARK ALL DRIVES AS NEEDING RECALIBRATION - ; NOTE THAT IF THE VALUE IS CURRENT $FF, + ; NOTE THAT IF THE VALUE IS CURRENTLY $FF, ; WE NEED TO LEAVE IT ALONE, SO WE 'OR' IN THE ; $FE TO AVOID THIS SCENARIO. @@ -963,8 +978,14 @@ FD_RETRY: CALL FC_PRTRESULTS #ENDIF + ; RETURN APPROPRIATE HBIOS ERROR LD A,(FST_RC) - OR A ; OTHERWISE SET FLAGS BASED ON RC (IN A) + CP FRC_NOTWRIT + LD A,ERR_READONLY ; ASSUME WRITE PROTECTED ERROR + JR Z,FD_RETRY1 + LD A,ERR_IO ; OTHERWISE I/O ERROR +FD_RETRY1: + OR A ; SET FLAGS RET ; AND GIVE UP ; ; @@ -1033,7 +1054,10 @@ FD_RUN1: JR Z,FC_WRITE CP DOP_READID JR Z,FC_READID - CALL PANIC + CALL SYSCHK + LD A,ERR_NOFUNC + OR A + RET FD_RUNCHK: #IF (DSKYENABLE) @@ -1235,7 +1259,7 @@ FC_SETDOR ; ; SET FST_DCR ; -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO)) +#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO) | (FDMODE == FDMODE_EPFDC)) ; FC_SETDCR LD (FST_DCR),A @@ -1267,7 +1291,7 @@ FC_RESETFDC: #IF ((FDMODE == FDMODE_ZETA) | (FDMODE == FDMODE_DIO3) | (FDMODE == FDMODE_RCSMC)) RES 7,A #ENDIF -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO)) +#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO) | (FDMODE == FDMODE_EPFDC)) LD A,0 #ENDIF CALL FC_SETDOR @@ -1282,7 +1306,7 @@ FC_RESETFDC: ; PULSE TERMCT TO TERMINATE ANY ACTIVE EXECUTION PHASE ; FC_PULSETC: -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO)) +#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO) | (FDMODE == FDMODE_EPFDC)) IN A,(FDC_TC) #ELSE LD A,(FST_DOR) @@ -1299,7 +1323,7 @@ FC_MOTORON: ; LD BC,300H ; LD BC,50H ; LD (FCD_IDLECNT),BC - + LD A,(CB_CPUMHZ) RLCA LD (FCD_IDLECNT),A @@ -1339,7 +1363,7 @@ FC_MOTORON1: CP C ; COMPARE TO NEW MOTOR BITS RET Z ; SKIP DELAY, MOTOR WAS ALREADY ON #ENDIF -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO)) +#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_RCWDC) | (FDMODE == FDMODE_DYNO) | (FDMODE == FDMODE_EPFDC)) ; SETUP DCR FOR DIDE HARDWARE LD A,(FCD_DCR) ; GET NEW DCR VALUE CALL FC_SETDCR ; AND IMPLEMENT IT diff --git a/Source/HBIOS/flashlib.inc b/Source/HBIOS/flashlib.inc new file mode 100644 index 00000000..f9cc6fa3 --- /dev/null +++ b/Source/HBIOS/flashlib.inc @@ -0,0 +1,373 @@ +;====================================================================== +; FLASH LIBRARY +;====================================================================== +; FLASH IDENTIFY +; SELECT THE APPROPRIATE BANK / ADDRESS +; ISSUE ID COMMAND +; READ IN ID WORD +; ISSUE ID EXIT COMMAND +; SELECT ORIGINAL BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; A CONTAINS CURRENT BANK +; ON EXIT BC CONTAINS ID WORD +; NO STATUS IS RETURNED +;====================================================================== +; + .DB MD_I_SZ ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +MD_FIDEN_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + LD D,A ; SAVE CURRENT BANK +; + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO PROGRAM +; + LD HL,$5555 ; LD A,$AA ; COMMAND + LD (HL),$AA ; LD ($5555),A ; SETUP + LD A,H ; LD A,$55 + LD ($2AAA),A ; LD ($2AAA),A + LD (HL),$90 ; LD A,$90 +; ; LD ($5555),A + LD BC,($0000) ; READ ID +; + LD A,$F0 ; LD A,$F0 ; EXIT + LD (HL),A ; LD ($5555),A ; COMMAND +; + LD A,D ; RETURN TO ORIGINAL BANK + JP HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY +; +MD_I_SZ .EQU $-MD_FIDEN_R ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; ERASE FLASH SECTOR. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; ISSUE ERASE SECTOR COMMAND +; POLL TOGGLE BIT FOR COMPLETION STATUS. +; SELECT ORIGINAL BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; A CONTAINS CURRENT BANK +; ON EXIT C RETURNS STATUS 0=SUCCESS NZ=FAIL +;====================================================================== +; + .DB MD_S_SZ ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +MD_FERAS_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + PUSH AF ; SAVE CURRENT BANK + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO PROGRAM +; + LD HL,$5555 ; LD ($5555),A + LD DE,$2AAA ; LD A,$55 + LD A,L ; LD ($2AAA),A + LD (HL),E ; LD A,$80 + LD (DE),A ; LD ($5555),A + LD (HL),$80 ; LD A,$AA + LD (HL),E ; LD ($5555),A + LD (DE),A ; LD A,$55 +; ; LD ($2AAA),A + LD H,C ; SECTOR + LD L,$00 ; ADDRESS +; + LD A,$30 ; SECTOR ERASE + LD (HL),A ; COMMAND +; +MD_WT4: LD A,(HL) ; DO TWO SUCCESSIVE READS + LD C,(HL) ; FROM THE SAME FLASH ADDRESS. + XOR C ; IF THE SAME ON BOTH READS + BIT 6,A ; THEN ERASE IS COMPLETE SO EXIT. +; + JR Z,MD_WT5 ; BIT 6 = 0 IF SAME ON SUCCESSIVE READS = COMPLETE + ; BIT 6 = 1 IF DIFF ON SUCCESSIVE READS = INCOMPLETE +; + LD A,C ; OPERATION IS NOT COMPLETE. CHECK TIMEOUT BIT (BIT 5). + BIT 5,C ; IF NO TIMEOUT YET THEN LOOP BACK AND KEEP CHECKING TOGGLE STATUS + JR Z,MD_WT4 ; IF BIT 5=0 THEN RETRY; NZ TRUE IF BIT 5=1 +; + LD A,(HL) ; WE GOT A TIMOUT. RECHECK TOGGLE BIT IN CASE WE DID COMPLETE + XOR (HL) ; THE OPERATION. DO TWO SUCCESSIVE READS. ARE THEY THE SAME? + BIT 6,A ; IF THEY ARE THEN OPERATION WAS COMPLETED + JR Z,MD_WT5 ; OTHERWISE ERASE OPERATION FAILED OR TIMED OUT. +; + LD C,$F0 ; COMMON FAIL STATUS / PREPARE DEVICE RESET CODE + LD (HL),C ; WRITE DEVICE RESET + JR MD_WT6 +MD_WT5: LD C,L ; SET SUCCESS STATUS +; +MD_WT6: POP AF ; RETURN TO ORIGINAL BANK + JP HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY +; +MD_S_SZ .EQU $-MD_FERAS_R ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; FLASH READ SECTOR. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; READ SECTOR OF 4096 BYTES, BYTE AT A TIME +; SELECT SOURCE BANK, READ DATA, +; SELECT DESTINATION BANK, WRITE DATA +; DESTINATION BANK IS ALWAYS CURRENT BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; DE = 0000 BYTE COUNT +; IX POINTS TO DATA TO BE WRITTEN +; A CONTAINS CURRENT BANK +; ON EXIT NO STATUS RETURNED +;====================================================================== +; + .DB MD_R_SZ ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +MD_FREAD_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + LD H,C ; SECTOR + LD L,D ; ADDRESS +; + PUSH AF ; SAVE CURRENT BANK +; +MD_FRD1:LD A,B ; CHANGE TO SOURCE BANK + CALL HBX_BNKSEL ; READ + LD C,(HL) ; BYTE +; + POP AF ; RESTORE CURRENT BANK + PUSH AF ; AND SAVE A COPY FOR NEXT LOOP + CALL HBX_BNKSEL ; SELECT BANK TO WRITE TO +; + LD (IX+0),C ; WRITE BYTE +; + INC HL ; NEXT SOURCE LOCATION + INC IX ; NEXT DESTINATION LOCATION +; + INC DE ; CONTINUE READING UNTIL + BIT 4,D ; WE HAVE DONE ONE SECTOR + JR Z,MD_FRD1 +; + POP AF + RET +; +MD_R_SZ .EQU $-MD_FREAD_R ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; FLASH VERIFY SECTOR. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; VERIFY SECTOR OF 4096 BYTES, BYTE AT A TIME +; SELECT SOURCE BANK, READ DATA, +; SELECT DESTINATION BANK, COMPARE DATA +; DESTINATION BANK IS ALWAYS CURRENT BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; DE = 0000 BYTE COUNT +; IX POINTS TO DATA TO BE VERIFIED +; A CONTAINS CURRENT BANK +; ON EXIT C RETURNS STATUS 0=SUCCESS NZ=FAIL +;====================================================================== +; + .DB MD_V_SZ ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +MD_FVERI_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + LD H,C ; SECTOR + LD L,D ; ADDRESS +; + PUSH AF ; SAVE CURRENT BANK +; +MD_FVE1:LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO READ + LD C,(HL) ; READ BYTE +; + POP AF ; RESTORE CURRENT BANK + PUSH AF ; AND SAVE A COPY FOR NEXT LOOP + CALL HBX_BNKSEL ; TO VERIFY AGAINST +; + LD A,C + SUB (IX+0) ; COMPARE BYTE + LD C,A ; SET STATUS + JR NZ,MD_FVE2 ; EXIT IF MISMATCH +; + INC HL ; NEXT SOURCE LOCATION + INC IX ; NEXT DESTINATION LOCATION +; + INC DE ; CONTINUE READING UNTIL + BIT 4,D ; WE HAVE DONE ONE SECTOR + JR Z,MD_FVE1 +; +MD_FVE2:POP AF + RET +; +MD_V_SZ .EQU $-MD_FVERI_R ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; FLASH WRITE SECTOR. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; WRITE 1 SECTOR OF 4096 BYTES, BYTE AT A TIME +; ISSUE WRITE BYTE COMMAND AND WRITE THE DATA BYTE +; POLL TOGGLE BIT FOR COMPLETION STATUS. +; SELECT ORIGINAL BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; IX POINTS TO DATA TO BE WRITTEN +; DE = 0000 BYTE COUNT +; A CONTAINS CURRENT BANK +; ON EXIT NO STATUS IS RETURNED +;====================================================================== +; + .DB MD_W_SZ ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +MD_FWRIT_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + LD H,C ; SECTOR + LD L,D ; ADDRESS +; + PUSH AF ; SAVE CURRENT BANK +MD_FWR1:CALL HBX_BNKSEL ; SELECT BANK TO READ +; + LD C,(IX+0) ; READ IN BYTE +; + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO PROGRAM +; + LD A,$AA ; COMMAND + LD ($5555),A ; SETUP + LD A,$55 + LD ($2AAA),A +; + LD A,$A0 ; WRITE + LD ($5555),A ; COMMAND +; + LD (HL),C ; WRITE OUT BYTE +; +; ; DO TWO SUCCESSIVE READS +MD_FWR2:LD A,(HL) ; FROM THE SAME FLASH ADDRESS. + LD C,(HL) ; IF TOGGLE BIT (BIT 6) + XOR C ; IS THE SAME ON BOTH READS + BIT 6,A ; THEN WRITE IS COMPLETE SO EXIT. + JR NZ,MD_FWR2 ; Z TRUE IF BIT 6=0 I.E. "NO TOGGLE" WAS DETECTED. +; + INC HL ; NEXT DESTINATION LOCATION + INC IX ; NEXT SOURCE LOCATION +; + POP AF ; RESTORE CURRENT BANK + PUSH AF ; AND SAVE A COPY FOR NEXT LOOP +; + INC DE ; CONTINUE WRITING UNTIL + BIT 4,D ; WE HAVE DONE ONE SECTOR + JR Z,MD_FWR1 +; + POP AF ; RESTORE CURRENT BANK + JP HBX_BNKSEL ; RETURN TO ORIGINAL BANK WHICH IS OUR RAM BIOS COPY +; +MD_W_SZ .EQU $-MD_FWRIT_R ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; ERASE FLASH CHIP. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; ISSUE ERASE COMMAND +; POLL TOGGLE BIT FOR COMPLETION STATUS. +; SELECT ORIGINAL BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; A CONTAINS CURRENT BANK +; ON EXIT A RETURNS STATUS 0=SUCCESS FF=FAIL +;====================================================================== +; + .DB MD_E_SZ ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +MD_FERAC_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + PUSH AF ; SAVE CURRENT BANK + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO PROGRAM +; + LD HL,$5555 ; LD A,$AA ; COMMAND + LD (HL),$AA ; LD ($5555),A ; SETUP + LD A,L ; LD A,$55 + LD ($2AAA),A ; LD ($2AAA),A + LD (HL),$80 ; LD A,$80 + LD (HL),$AA ; LD ($5555),A + LD A,L ; LD A,$AA + LD ($2AAA),A ; LD ($5555),A + LD (HL),$10 ; LD A,$55 + ; LD ($2AAA),A + ; LD A,$10 + ; LD ($5555),A +; +FF_WT2: LD A,(HL) ; DO TWO SUCCESSIVE READS FROM THE SAME FLASH ADDRESS. + LD C,(HL) ; IF TOGGLE BIT (BIT 6) + XOR C ; IS THE SAME ON BOTH READS + BIT 6,A ; THEN ERASE IS COMPLETE SO EXIT. + JR Z,FF_WT1 ; Z TRUE IF BIT 6=0 I.E. "NO TOGGLE" WAS DETECTED. +; + LD A,C ; OPERATION IS NOT COMPLETE. CHECK TIMEOUT BIT (BIT 5). + BIT 5,C ; IF NO TIMEOUT YET THEN LOOP BACK AND KEEP CHECKING TOGGLE STATUS + JR Z,FF_WT2 ; IF BIT 5=0 THEN RETRY; NZ TRUE IF BIT 5=1 +; + LD A,(HL) ; WE GOT A TIMEOUT. RECHECK TOGGLE BIT IN CASE WE DID COMPLETE + XOR (HL) ; THE OPERATION. DO TWO SUCCESSIVE READS. ARE THEY THE SAME? + BIT 6,A ; IF THEY ARE THEN OPERATION WAS COMPLETED + JR Z,FF_WT1 ; OTHERWISE ERASE OPERATION FAILED OR TIMED OUT. +; + LD (HL),$F0 ; WRITE DEVICE RESET + LD C,$FF ; SET FAIL STATUS + JR FF_WT3 +; +FF_WT1: LD C,0 ; SET SUCCESS STATUS +FF_WT3: POP AF +; LD A,B ; RETURN TO ORIGINAL BANK + JP HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY +; +MD_E_SZ .EQU $-MD_FERAC_R ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED + +;====================================================================== +; +; RELOCATABLE CODE SPACE REQUIREMENTS CHECK +; +;====================================================================== +; +MD_CSIZE .EQU 0 +; +#IF (MD_W_SZ>MD_CSIZE) +MD_CSIZE .SET MD_W_SZ +#ENDIF +#IF (MD_S_SZ>MD_CSIZE) +MD_CSIZE .SET MD_S_SZ +#ENDIF +#IF (MD_I_SZ>MD_CSIZE) +MD_CSIZE .SET MD_I_SZ +#ENDIF +#IF (MD_R_SZ>MD_CSIZE) +MD_CSIZE .SET MD_R_SZ +#ENDIF +#IF (MD_V_SZ>MD_CSIZE) +MD_CSIZE .SET MD_V_SZ +#ENDIF +#IF (MD_E_SZ>MD_CSIZE) +MD_CSIZE .SET MD_E_SZ +#ENDIF +; +#IF (MD_CSIZE>64) + .ECHO "Warning: Flash code exceeds available space by " + .ECHO MD_CSIZE-64 + .ECHO " bytes.\n" + .ECHO "MD_FIDEN_R " + .ECHO MD_I_SZ + .ECHO "\n" +; + .ECHO "MD_FREAD_R " + .ECHO MD_R_SZ + .ECHO "\n" +; + .ECHO "MD_FVERI_R " + .ECHO MD_V_SZ + .ECHO "\n" +; + .ECHO "MD_FERAS_R " + .ECHO MD_S_SZ + .ECHO "\n" +; + .ECHO "MD_FWRIT_R " + .ECHO MD_W_SZ + .ECHO "\n" +; + .ECHO "MD_FERAC_R " + .ECHO MD_E_SZ + .ECHO "\n" +#ENDIF \ No newline at end of file diff --git a/Source/HBIOS/game.asm b/Source/HBIOS/game.asm index 8bbce38b..43d90b87 100644 --- a/Source/HBIOS/game.asm +++ b/Source/HBIOS/game.asm @@ -300,9 +300,14 @@ EXIT: ; CALL BDOS CALL PRTSTRDE - LD A,00H - LD HL,0000H - JP 0FFF9H + ;LD A,00H + ;LD HL,0000H + ;JP 0FFF9H + + LD B,0F0H + LD C,01H + CALL 0FFF0H + ; RET ISOVER: diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 03e4284f..5f3bcf0e 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -64,7 +64,6 @@ ; - dsky.asm ; - unlzsa2s.asm ; -; ; INCLUDE GENERIC STUFF ; #INCLUDE "std.asm" @@ -112,16 +111,49 @@ MODCNT .SET MODCNT + 1 ; NO INTERRUPT HANDLING #DEFINE HB_DI ; #DEFINE HB_EI ; -#ENDIF -#IF ((INTMODE == 1) | (INTMODE == 2)) -; MODE 1 OR 2 INTERRUPT HANDLING +#ELSE + #IF (CPUFAM == CPU_Z280) + #IF (INTMODE == 3) +; Z280 MODE 3 INTERRUPT HANDLING (INTA, C/T 0, & UART RCVR ENABLED) +#DEFINE HB_DI DI +;#DEFINE HB_DI .DB $ED,$77,$7F +;#DEFINE HB_EI EI +#DEFINE HB_EI .DB $ED,$7F,$0B + #ELSE +; Z280 MODE 1/2 INTERRUPT HANDLING +#DEFINE HB_DI DI +#DEFINE HB_EI EI + #ENDIF + #ELSE #DEFINE HB_DI DI #DEFINE HB_EI EI + #ENDIF #ENDIF -#IF (INTMODE > 2) +; +#IF (INTMODE > 3) .ECHO "*** ERROR: INVALID INTMODE SETTING!!!\n" !!! ; FORCE AN ASSEMBLY ERROR #ENDIF +#IF (INTMODE == 3) + #IF (CPUFAM != CPU_Z280) + .ECHO "*** ERROR: INTMODE 3 REQUIRES Z280 FAMILY CPU!!!\n" + !!! ; FORCE AN ASSEMBLY ERROR + #ENDIF + #IF (MEMMGR != MM_Z280) + .ECHO "*** ERROR: INTMODE 3 REQUIRES Z280 MEMORY MANAGER!!!\n" + !!! ; FORCE AN ASSEMBLY ERROR + #ENDIF +#ENDIF +#IF (MEMMGR == MM_Z280) + #IF (INTMODE != 3) + .ECHO "*** ERROR: Z280 MEMORY MANAGER REQUIRES INTMODE 3!!!\n" + !!! ; FORCE AN ASSEMBLY ERROR + #ENDIF + #IF (CPUFAM != CPU_Z280) + .ECHO "*** ERROR: Z280 MEMORY MANAGER REQUIRES Z280 FAMILY CPU!!!\n" + !!! ; FORCE AN ASSEMBLY ERROR + #ENDIF +#ENDIF ; ; ; @@ -215,6 +247,8 @@ CB_SERDEV .DB 0 ; PRIMARY SERIAL UNIT IS UNIT #0 BY FIAT CB_CRTDEV .DB $FF ; PRIMARY CRT UNIT, $FF UNTIL AFTER HBIOS INIT CB_CONDEV .DB $FF ; CONSOLE UNIT, $FF UNTIL AFTER HBIOS INIT ; +CB_DIAGLVL .DB DIAGLVL ; ROMWBW HBIOS DIAGNOSTIC LEVEL +; ; MEMORY MANAGEMENT VARIABLES START AT $20 ; .FILL (HCB + $20 - $),0 @@ -275,10 +309,7 @@ HBX_IDENT: ; ACCOMMODATE FREERTOS. HBX_BUF IS ONLY USED AS A BOUNCE BUFFER, SO IT'S ; USE WILL NEVER OVERLAP WITH BELOW. ; -; HBX_INVOKE IS NOT RE-ENTRANT! HB_INVBNK CAN BE USED GLOBALLY TO DETERMINE -; IF HBIOS IS ALREADY ACTIVE. HB_INVBNK WILL HAVE A VALUE != $FF WHEN HBIOS -; IS ACTIVE. ON RETURN, HB_INVBNK IS SET TO $FF TO INDICATE HBIOS IS NOT -; ACTIVE. +; WARNING: HBX_INVOKE IS *NOT* REENTRANT! ; HBX_INVOKE: @@ -290,6 +321,24 @@ HBX_INVOKE: POP HL ; RESTORE HL #ENDIF +#IF (MEMMGR == MM_Z280) + + LD A,(HB_CURBNK) ; GET CURRENT BANK + LD (HB_INVBNK),A ; SAVE INVOCATION BANK + + LD A,BID_BIOS ; HBIOS BANK + LD (HB_CURBNK),A ; SET AS CURRENT BANK + + .DB $ED,$71 ; SC + .DW HB_DISPATCH ; SC PARAMETER + + PUSH AF + LD A,(HB_INVBNK) + LD (HB_CURBNK),A + POP AF + +#ELSE + LD (HBX_INVSP),SP ; SAVE ORIGINAL STACK FRAME LD SP,HBX_BUF_END ; BORROW HBX_BUF FOR TEMP STACK @@ -311,6 +360,8 @@ HBX_INVOKE: LD SP,0 ; RESTORE ORIGINAL STACK FRAME HBX_INVSP .EQU $ - 2 +#ENDIF + #IF (HBIOS_MUTEX == TRUE) PUSH HL ; SAVE HL LD HL,HB_LOCK ; POINT TO LOCK @@ -359,6 +410,7 @@ HBX_ROM: OUT (MPCL_ROM),A ; SET ROM PAGE SELECTOR RET ; DONE #ENDIF +; #IF (MEMMGR == MM_Z2) BIT 7,A ; BIT 7 SET REQUESTS RAM PAGE JR Z,HBX_ROM ; NOT SET, SELECT ROM PAGE @@ -368,11 +420,14 @@ HBX_ROM: HBX_ROM: RLCA ; TIMES 2 - GET 16K PAGE INSTEAD OF 32K OUT (MPGSEL_0),A ; BANK_0: 0K - 16K - ;OUT (DIAGPORT),A ; *DEBUG* INC A ; OUT (MPGSEL_1),A ; BANK_1: 16K - 32K +#IF (CPUFAM == CPU_Z280) + .DB $ED,$65 ; PCACHE +#ENDIF RET ; DONE #ENDIF +; #IF (MEMMGR == MM_N8) BIT 7,A ; TEST BIT 7 FOR RAM VS. ROM JR Z,HBX_ROM ; IF NOT SET, SELECT ROM PAGE @@ -394,8 +449,8 @@ HBX_ROM: LD A,N8_DEFACR ; SELECT ROM BY CLEARING BIT 7 OUT0 (N8_ACR),A ; ... IN N8 ACR REGISTER RET ; DONE -; #ENDIF +; #IF (MEMMGR == MM_Z180) RLCA ; RAM FLAG TO CARRY FLAG AND BIT 0 JR NC,HBX_BNKSEL1 ; IF NC, WANT ROM PAGE, SKIP AHEAD @@ -407,6 +462,28 @@ HBX_BNKSEL1: RET ; DONE #ENDIF ; +#IF (MEMMGR == MM_Z280) + PUSH BC ; SAVE BC + PUSH HL ; SAVE HL + LD B,$00 ; FIRST USER PDR + .DB $ED,$71 ; SC + .DW Z280_BNKSEL ; SC PARAMETER + POP HL ; RESTORE HL + POP BC ; RESTORE BC + RET ; DONE +#ENDIF +; +#IF (MEMMGR == MM_ZRC) + BIT 7,A ; BIT 7 SET REQUESTS RAM PAGE + JR Z,HBX_ROM ; NOT SET, SELECT ROM PAGE + RES 7,A ; RAM PAGE REQUESTED: CLEAR ROM BIT + ADD A,$10 ; ADD 16 x 32K - RAM STARTS FROM 512K +; +HBX_ROM: + OUT ($1F),A ; HCS WRITE TO THE BANK CONTROL REGISTER + RET ; DONE +#ENDIF +; ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Copy Data - Possibly between banks. This resembles CP/M 3, but ; usage of the HL and DE registers is reversed. @@ -422,11 +499,24 @@ HBX_BNKSEL1: ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; HBX_BNKCPY: -#IF (INTMODE > 0) +#IF (MEMMGR == MM_Z280) + .DB $ED,$71 ; SC + .DW Z280_BNKCPY ; SC PARAMETER + RET +#ELSE + #IF (CPUFAM == CPU_Z280) + PUSH HL + PUSH BC + LD C,Z280_MSR + .DB $ED,$66 ; LDCTL HL,(C) + POP BC + EX (SP),HL + HB_DI + #ELSE LD A,I - DI + HB_DI PUSH AF -#ENDIF + #ENDIF LD (HBX_BC_SP),SP ; PUT STACK LD SP,HBX_TMPSTK ; ... IN HI MEM @@ -456,11 +546,18 @@ HBX_BC_LAST: LD SP,$FFFF ; RESTORE STACK HBX_BC_SP .EQU $ - 2 ; ... TO ORIGINAL VALUE -#IF (INTMODE > 0) + #IF (CPUFAM == CPU_Z280) + EX (SP),HL ; SAVE HL, RECOVER MSR + PUSH BC ; SAVE BC + LD C,Z280_MSR + .DB $ED,$6E ; LDCTL (C),HL + POP BC ; RECOVER BC + POP HL ; RECOVER HL + #ELSE POP AF JP PO,$+4 - EI -#ENDIF + HB_EI + #ENDIF RET ; HBX_BC_ITER: @@ -481,25 +578,41 @@ HBX_BC_ITER: POP HL ; RECOVER UPDATED SRC ADR ; HL = UPDATED SRC, DE = UPDATED DEST, BC = 0 RET +#ENDIF ; ; CALL A ROUTINE IN ANOTHER BANK. ; CALLER MUST ENSURE STACK IS ALREADY IN HIGH MEMORY AND HAS ADEQUATE SPACE. ; IF IM1 INTERRUPTS ARE POSSIBLE, CALLER MUST EITHER DISABLE THEM PRIOR TO ; BNKCALL OR MAKE SURE THAT PAGE ZERO IN TARGET BANK IS PREPARED FOR THEM. -; ON INPUT A=TARGET BANK, HL=TARGET ADDRESS +; ON INPUT A=TARGET BANK, IX=TARGET ADDRESS ; HBX_BNKCALL: - LD (HBX_TGTBNK),A ; STUFF TARGET BANK TO CALL INTO CODE BELOW - LD (HBX_TGTADR),HL ; STUFF ADDRESS TO CALL INTO CODE BELOW +; +#IF (MEMMGR == MM_Z280) + CP BID_BIOS ; CALLING HBIOS? + JR NZ,HBX_BNKCALL3 ; NOPE, DO NORMAL PROCESSING + .DB $ED,$71 ; SC + .DW HBX_BNKCALL2 ; CALL HERE IN SYSTEM MODE + RET ; THEN RETURN + +HBX_BNKCALL2: + HB_EI ; INTS ARE OK + LD (HBX_BNKCALL_GO+1),IX ; SETUP DEST ADR + .DB $ED,$65 ; PCACHE (CRITICAL!!!) +HBX_BNKCALL_GO: + JP $FFFF ; DO THE REAL WORK AND RETURN +#ENDIF + +HBX_BNKCALL3: + LD (HBX_BNKCALL_BNK+1),A ; STUFF TARGET BANK TO CALL INTO CODE BELOW + LD (HBX_BNKCALL_ADR+1),IX ; STUFF ADDRESS TO CALL INTO CODE BELOW LD A,(HB_CURBNK) ; GET CURRENT BANK PUSH AF ; SAVE FOR RETURN -HBX_TGTBNK .EQU $ + 1 +HBX_BNKCALL_BNK: LD A,$FF ; LOAD BANK TO CALL ($FF OVERLAID AT ENTRY) CALL HBX_BNKSEL ; ACTIVATE THE NEW BANK - -HBX_TGTADR .EQU $ + 1 +HBX_BNKCALL_ADR: CALL $FFFF ; CALL ROUTINE ($FFFF IS OVERLAID ABOVE) - EX (SP),HL ; SAVE HL AND GET BANK TO RESTORE IN HL PUSH AF ; SAVE AF LD A,H ; BANK TO RESTORE TO A @@ -543,6 +656,9 @@ HBX_POKE: ; HBX_PPRET: POP AF +#IF (MEMMGR == MM_Z280) + LD A,(HB_INVBNK) ; SPECIAL CASE FOR Z280 MEM MGR +#ENDIF CALL HBX_BNKSEL LD SP,0 ; RESTORE ORIGINAL STACK FRAME HBX_PPSP .EQU $ - 2 @@ -563,7 +679,7 @@ HBX_INTSTK .EQU $ !!! ; FORCE AN ASSEMBLY ERROR #ENDIF ; -#IF (INTMODE == 2) +#IF ((INTMODE == 2) | (INTMODE == 3)) ; ; HBIOS INTERRUPT SLOT ASSIGNMENTS ; @@ -635,47 +751,83 @@ INT_IM1: ; #IF (INTMODE > 0) ; -; COMMON INTERRUPT DISPATCHING CODE -; SETUP AND CALL HANDLER IN BIOS BANK -; HBX_INT: ; COMMON INTERRUPT ROUTING CODE +; + #IF (MEMMGR == MM_Z280) ; EX (SP),HL ; SAVE HL AND GET INT JP TABLE OFFSET + + ; SAVE STATE (HL SAVED PREVIOUSLY ON ORIGINAL STACK FRAME) + PUSH AF ; SAVE AF + PUSH BC ; SAVE BC + PUSH DE ; SAVE DE + PUSH IY ; SAVE IY +; + ; HANDLE INT VIA JP TABLE IN HBIOS + LD L,(HL) ; OFFSET INTO JP TABLE FOR THIS INT + LD H,HB_IVT >> 8 ; MSB OF HBIOS INT JP TABLE + CALL JPHL ; CALL HANDLER VIA INT JP TABLE +; + ; RESTORE STATE + POP IY ; RESTORE IY + POP DE ; RESTORE DE + POP BC ; RESTORE BC + POP AF ; RESTORE AF + POP HL ; RESTORE HL +; + ; BURN THE REASON CODE + EX (SP),HL ; HL TO STK, RC TO HL + POP HL ; RESTORE HL + CALL HBX_RETI ; RETI FOR Z80 PERIPHERALS + .DB $ED,$55 ; RETIL +; +HBX_RETI: + RETI +; + #ELSE +; +; COMMON INTERRUPT DISPATCHING CODE +; SETUP AND CALL HANDLER IN BIOS BANK +; + EX (SP),HL ; SAVE HL AND GET INT JP TABLE OFFSET +; LD (HBX_INT_SP),SP ; SAVE ORIGINAL STACK FRAME LD SP,HBX_INTSTK ; USE DEDICATED INT STACK FRAME IN HI MEM - +; ; SAVE STATE (HL SAVED PREVIOUSLY ON ORIGINAL STACK FRAME) PUSH AF ; SAVE AF PUSH BC ; SAVE BC PUSH DE ; SAVE DE PUSH IY ; SAVE IY - +; LD A,BID_BIOS ; HBIOS BANK CALL HBX_BNKSEL_INT ; SELECT IT - +; LD L,(HL) ; OFFSET INTO JP TABLE FOR THIS INT LD H,HB_IVT >> 8 ; MSB OF HBIOS INT JP TABLE - +; CALL JPHL ; CALL HANDLER VIA INT JP TABLE - +; LD A,(HB_CURBNK) ; GET PRE-INT BANK CALL HBX_BNKSEL ; SELECT IT - +; ; RESTORE STATE POP IY ; RESTORE IY POP DE ; RESTORE DE POP BC ; RESTORE BC POP AF ; RESTORE AF - +; LD SP,$FFFF ; RESTORE ORIGINAL STACK FRAME HBX_INT_SP .EQU $ - 2 - +; POP HL ; RESTORE HL - +; HB_EI ; ENABLE INTERRUPTS RETI ; AND RETURN ; + #ENDIF + #ENDIF ; ; SMALL TEMPORARY STACK FOR USE BY HBX_BNKCPY @@ -734,7 +886,7 @@ HB_ENTRYTBL .EQU $ JP HB_START ; HBIOS INITIALIZATION JP HB_DISPATCH ; VECTOR TO DISPATCHER ; -HB_STKSIZ .EQU HB_ENTRYTBL + 256 - $ +HB_STKSIZ .EQU $100 - ($ & $FF) ; .FILL HB_STKSIZ,$FF ; USE REMAINDER OF PAGE FOR HBIOS STACK HB_STACK .EQU $ ; TOP OF HBIOS STACK @@ -784,7 +936,7 @@ HB_IVT: ; NOTE THAT EACH ENTRY HAS A FILLER BYTE OF VALUE ZERO. THIS BYTE ; HAS NO FUNCTION. IT IS JUST USED TO MAKE ENTRIES AN EVEN 4 BYTES. ; -#IF (INTMODE == 2) +#IF ((INTMODE == 2) | (INTMODE == 3)) ; HB_IVT: HB_IVT00: JP HB_BADINT \ .DB 0 @@ -811,6 +963,23 @@ HB_IVT0F: JP HB_BADINT \ .DB 0 ;================================================================================================== ; HB_START: +#IFDEF APPBOOT + #IF (MEMMGR == MM_Z280) + LD A,%00000001 + OUT (DIAGPORT),A + LD DE,Z280_BOOTERR + LD C,9 + LD A,%00000010 + OUT (DIAGPORT),A + CALL $0005 + LD A,%00001000 + OUT (DIAGPORT),A + RET +; +Z280_BOOTERR .TEXT "\r\n\r\n*** Application mode boot not supported under Z280 native memory management!!!\r\n\r\n$" + #ENDIF +#ENDIF + DI ; NO INTERRUPTS IM 1 ; INTERRUPT MODE 1 ; @@ -821,10 +990,97 @@ HB_START: ; LD SP,HBX_LOC ; SETUP INITIAL STACK JUST BELOW HBIOS PROXY ; +#IF (CPUFAM == CPU_Z280) + ; SET MAXIMUM I/O WAIT STATES FOR NOW + LD C,Z280_BTCR ; BUS TIMING AND CONTROL REGISTER + LD HL,$0033 ; 3 I/O WAIT STATES ADDED + .DB $ED,$6E ; LDCTL (C),HL + + #IF (MEMMGR == MM_Z280) + + ; INITIALIZE MMU + ; START BY SELECTING I/O PAGE $FF + LD L,$FF ; MMU AND DMA PAGE I/O REG IS $FF + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; INITIALIZE ALL OF THE SYSTEM PAGE DESCRIPTORS WITH BLOCK MOVE + XOR A ; FIRST USER PDR + OUT (Z280_MMUPDRPTR),A ; SET THE PDR POINTER + LD HL,Z280_BOOTPDRTBL ; START OF PDR VALUES TABLE + LD C,Z280_MMUBLKMOV ; PDR BLOCK MOVE PORT + LD B,16 ; PROGRAM 16 PDRS + .DB $ED,$93 ; OTIRW +; + ; INITIALIZE ALL OF THE USER PAGE DESCRIPTORS WITH BLOCK MOVE + LD A,$10 ; FIRST SYSTEM PDR + OUT (Z280_MMUPDRPTR),A ; SET THE PDR POINTER + LD HL,Z280_BOOTPDRTBL ; START OF PDR VALUES TABLE + LD C,Z280_MMUBLKMOV ; PDR BLOCK MOVE PORT + LD B,16 ; PROGRAM 16 PDRS + .DB $ED,$93 ; OTIRW +; + ; ENABLE MMU (SYSTEM AND USER TRANSLATION) + LD C,Z280_MMUMCR ; MMU MASTER CONTROL REGISTER + LD HL,$BBFF ; ENABLE USER & SYSTEM TRANSLATE + .DB $ED,$BF ; OUTW (C),HL +; + ; DISABLE MEMORY REFRESH CYCLES + LD A,$08 ; DISABLED + OUT (Z280_RRR),A ; SET REFRESH RATE REGISTER +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; CONFIGURE Z280 INT/TRAP VECTOR TABLE POINTER REGISTER + ; WILL POINT TO ROM COPY FOR NOW, UPDATED TO RAM LATER ON + LD C,Z280_VPR + LD HL,Z280_IVT >> 8 ; TOP 16 BITS OF PHYSICAL ADR OF IVT + .DB $ED,$6E ; LDCTL (C),HL +; + JP Z280_INITZ ; JUMP TO CODE CONTINUATION +; +#IF (($ % 2) == 1) + ; BYTE ALIGN THE TABLE + .DB 0 +#ENDIF +; +Z280_BOOTPDRTBL: + ; LOWER 32 K (BANKED) + .DW ($000 << 4) | $A + .DW ($001 << 4) | $A + .DW ($002 << 4) | $A + .DW ($003 << 4) | $A + .DW ($004 << 4) | $A + .DW ($005 << 4) | $A + .DW ($006 << 4) | $A + .DW ($007 << 4) | $A + ; UPPER 32 K (COMMON) + .DW ($0F8 << 4) | $A + .DW ($0F9 << 4) | $A + .DW ($0FA << 4) | $A + .DW ($0FB << 4) | $A + .DW ($0FC << 4) | $A + .DW ($0FD << 4) | $A + .DW ($0FE << 4) | $A + .DW ($0FF << 4) | $A +; +Z280_INITZ: +; + #ENDIF +; +#ENDIF +; #IF (CPUFAM == CPU_Z180) ; SET BASE FOR CPU IO REGISTERS + ; DO NOT USE Z180_ICR FROM Z180.INC BECAUSE THE ICR + ; IS NOT YET AT THE RUNNING LOCATION. AT RESET, THE Z180 + ; REGISTER BASE I/O ADDRESS IS ZERO, SO INITIALLY, ICR IS + ; AT $3F. LD A,Z180_BASE - OUT0 (Z180_ICR),A + OUT0 ($3F),A ; AT RESET, ICR IS AT $3F DIAG(%00000010) @@ -862,6 +1118,10 @@ HB_START: ;#ENDIF LD A,(RAMSIZE + RAMBIAS - 64) >> 2 OUT0 (Z180_CBR),A ; COMMON BASE = LAST (TOP) BANK + + ; SET DEFAULT CSIO SPEED (INTERNAL CLOCK, SLOW AS POSSIBLE) + LD A,Z180_CNTR_DEF ; DIV 1280, 14KHZ @ 18MHZ CLK + OUT0 (Z180_CNTR),A #ENDIF ; #ENDIF @@ -966,10 +1226,16 @@ HB_START: ; ; TRANSITION TO HBIOS IN RAM BANK ; +#IF (MEMMGR == MM_Z280) + LD A,BID_BIOS + LD B,$10 ; FIRST SYSTEM PDR + CALL Z280_BNKSEL +#ELSE LD A,BID_BIOS ; BIOS BANK ID - LD HL,HB_START1 ; EXECUTION RESUMES HERE + LD IX,HB_START1 ; EXECUTION RESUMES HERE CALL HBX_BNKCALL ; CONTINUE IN RAM BANK, DO NOT RETURN HALT ; WE SHOULD NOT COME BACK HERE! +#ENDIF ; HB_RAMFLAG .DB FALSE ; INITIALLY FALSE, SET TO TRUE BELOW AFTER RAM TRANSITION ; @@ -986,6 +1252,13 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK LD A,TRUE ; ACCUM := TRUE LD (HB_RAMFLAG),A ; SET RAMFLAG ; +#IF (MEMMGR == MM_Z280) + ; NOW POINT TO RAM COPY OF Z280 INT/TRAP TABLE + LD C,Z280_VPR + LD HL,$0E80+(Z280_IVT >> 8) ; TOP 16 BITS OF PHYSICAL ADR OF IVT + .DB $ED,$6E ; LDCTL (C),HL +#ENDIF +; ; IF APPBOOT, WE NEED TO FIX UP A FEW THINGS IN PAGE ZERO ; #IFDEF APPBOOT @@ -1046,7 +1319,7 @@ SAVE_REC_M: LD (HB_BOOT_REC),A ; SAVE FOR LATER #ENDIF #IF (BT_REC_TYPE == BT_REC_SBCRI) - IN A,($68 + 6) ; UART_MSR MODEM + IN A,($68 + 6) ; UART_MSR MODEM BIT 6,A ; STATUS REGISTER LD A,0 ; BIT 6 JR Z,SAVE_REC_M ; IS RECOVERY MODE @@ -1094,12 +1367,13 @@ SAVE_REC_M: ; ; DISCOVER CPU TYPE ; -; THIS CODE IS DERIVED FROM UNA BY JOHN COFFMAN +; SOME OF THIS CODE IS DERIVED FROM UNA BY JOHN COFFMAN ; ; 0: Z80 ; 1: Z80180 - ORIGINAL Z180 (EQUIVALENT TO HD64180) ; 2: Z8S180 - ORIGINAL S-CLASS, REV. K, AKA SL1960, NO ASCI BRG ; 3: Z8S180 - REVISED S-CLASS, REV. N, W/ ASCI BRG +; 4: Z8280 ; LD HL,0 ; L = 0 MEANS Z80 ; @@ -1114,22 +1388,34 @@ SAVE_REC_M: INC L ; FLAG Z80180 OR BETTER ; ; TEST FOR OLDER S-CLASS (REV K) - IN0 A,(Z180_CCR) ; SUPPOSEDLY ONLY ON S-CLASS - INC A ; FF -> 0 + IN0 A,(Z180_CCR) ; SUPPOSEDLY ONLY ON S-CLASS + INC A ; FF -> 0 JR Z,HB_CPU1 INC L ; FLAG Z8S180 REV K (SL1960) OR BETTER ; ; TEST FOR NEWER S-CLASS (REV N) ; ON OLDER S-CLASS, ASCI TIME CONSTANT REG DOES NOT EXIST ; AND WILL ALWYAS READ BACK AS $FF - OUT0 (Z180_ASTC1L),D ; D = 0 AT THIS POINT - IN0 A,(Z180_ASTC1L) ; ASCI TIME CONSTANT REG - INC A ; FF -> 0 + OUT0 (Z180_ASTC1L),D ; D = 0 AT THIS POINT + IN0 A,(Z180_ASTC1L) ; ASCI TIME CONSTANT REG + INC A ; FF -> 0 JR Z,HB_CPU1 INC L ; FLAG Z8S180 REV N W/ ASCI BRG ; #ENDIF ; +#IF (CPUFAM == CPU_Z280) +; + ; TEST FOR Z280 PER ZILOG DOC + LD A,$40 ; INITIALIZE THE OPERAND + .DB $CB,$37 ; THIS INSTRUCTION WILL SET THE S FLAG + ; ON THE Z80 CPU AND CLEAR THE S FLAG + ; ON THE Z280 MPU. + JP M,HB_CPU1 ; IF Z80, SKIP AHEAD + LD L,4 ; WE ARE Z280 +; +#ENDIF +; HB_CPU1: LD A,L LD (HB_CPUTYPE),A @@ -1195,6 +1481,27 @@ HB_CPU2: ; #ENDIF ; +#IF (CPUFAM == CPU_Z280) +; + LD C,Z280_BTCR ; BUS TIMING AND CONTROL REG + .DB $ED,$66 ; LDCTL HL,(C) + LD A,L ; PUT IN A + AND %00111100 ; CLEAR DC AND I/O FIELDS + OR Z280_INTWAIT << 6 ; SET INT ACK WAIT STATES + OR Z280_IOWAIT ; SET I/O WAIT STATES + LD L,A ; BACK TO L + .DB $ED,$6E ; LDCTL (C),HL +; + LD C,Z280_BTIR ; BUS TIMING AND INIT REG + .DB $ED,$66 ; LDCTL HL,(C) + LD A,L ; PUT IN A + AND %11110011 ; CLEAR LOW MEM WAIT STATES + OR Z280_MEMWAIT << 2 ; SET LOW MEM WAIT STATES + LD L,A ; BACK TO L + .DB $ED,$6E ; LDCTL (C),HL +; +#ENDIF +; #IF (INTMODE == 2) ; SETUP Z80 IVT AND INT MODE 2 LD A,HBX_IVT >> 8 ; SETUP HI BYTE OF IVT ADDRESS @@ -1209,6 +1516,17 @@ HB_CPU2: IM 2 ; SWITCH TO INT MODE 2 #ENDIF ; +#IF (INTMODE == 3) +; + ; SETUP Z280 INT A FOR VECTORED INTERRUPTS + LD HL,%0010000000000000 + LD C,Z280_ISR + .DB $ED,$6E ; LDCTL (C),HL +; + .DB $ED,$4E ; IM 3 +; +#ENDIF +; #IF (PLATFORM == PLT_SBC) ; #IF (HTIMENABLE) ; SIMH TIMER @@ -1244,6 +1562,20 @@ HB_CPU2: LD (IVT(INT_TIM0)),HL ; Z180 TIMER 0 ; SETUP PERIODIC TIMER INTERRUPT ON TIMER 0 + ; *** THIS ASSUMES A TICKFREQ OF 50HZ!!! *** +; +#IF (TICKFREQ != 50) + .ECHO "TICKFREQ *MUST* BE 50 FOR Z180 TIMER\n" + !!! +#ENDIF +; + ; Z180 PRESCALES THE COUNTER BY 20 SO, + ; RLDR = CPU CLK / 20 / TICKFREQ + ; IF WE ASSUME TICKFREQ = 50, WE CAN SIMPIFY TO + ; RLDR = CPU CLK / 1000 + ; NOW IF DIVIDE BOTH SIDES BY 1000, WE CAN USE + ; CPUKHZ VALUE AND SIMPLIFY TO + ; RLDR = CPUKHZ LD HL,(CB_CPUKHZ) ; 50HZ = 18432000 / 20 / 50 / X, SO X = CPU KHZ OUT0 (Z180_TMDR0L),L ; INITIALIZE TIMER 0 DATA REGISTER OUT0 (Z180_TMDR0H),H @@ -1257,6 +1589,39 @@ HB_CPU2: ; #ENDIF ; +#IF (CPUFAM == CPU_Z280) +; + #IF (INTMODE == 3) +; +Z280_TC .EQU CPUOSC / 4 / 50 / 2 ; TIME CONSTANT +; + LD HL,Z280_TIMINT + LD (Z280_IVT+$16),HL ; Z280 T/C VECTOR +; + ; SELECT I/O PAGE $FE + LD L,$FE ; COUNTER/TIMER I/O PAGE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + LD A,%10100000 ; CONFIG: C, RE, IE + OUT (Z280_CT0_CFG),A ; SET C/T 0 + LD HL,Z280_TC ; TIME CONSTANT & COUNTER + LD C,Z280_CT0_TC ; SET C/T 0 + .DB $ED,$BF ; OUTW (C),HL + LD C,Z280_CT0_CT ; SET C/T 0 + .DB $ED,$BF ; OUTW (C),HL + LD A,%11100000 ; CMD: EN, GT + OUT (Z280_CT0_CMDST),A ; SET C/T 0 +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + #ENDIF +; +#ENDIF +; ; INITIALIZE HEAP STORAGE ; ; INITIALIZE POINTERS @@ -1284,7 +1649,7 @@ HB_CPU2: ; LD A,FORCECON ; CALCULATE PRE-INIT TABLE ; A IS INDEX OF CONSOLE DEVICE ENTRY RLCA ; ENTRY THAT WE WANT TO ; A IS OFFSET OF CONSOLE DEVICE ENTRY - LD DE,(HB_PCINITTBL) ; EXECUTE FIRST ; DE IS VALUE OF TOP ENTRY + LD DE,(HB_PCINITTBL) ; EXECUTE FIRST ; DE IS VALUE OF TOP ENTRY LD HL,HB_PCINITTBL ; HL IS ADDRESS OF TOP OF TABLE PUSH HL ; PUSH (1) TOP OF TABLE PUSH DE ; PUSH (2) VALUE OF TOP ENTRY @@ -1440,31 +1805,96 @@ HB_SPDTST: CALL PRTHEXBYTE #ENDIF ; +#IF (CPUFAM == CPU_Z280) + CALL PRTSTRD + .TEXT ", BUS @ $" + LD C,Z280_BTIR ; BUS TIMING AND CTL REG + .DB $ED,$66 ; LDCTL HL,(C) + LD A,L ; MOVE TO A + AND %00000011 ; ISOLATE CS FIELD + LD HL,(CB_CPUKHZ) ; GET CPU SPEED + CP %00000001 ; BUS @ 1/1 + JR Z,HB_Z280BUS ; GOT IT, SHOW IT + SRL H ; DIVIDE + RR L ; ... BY 2 + CP %00000000 ; BUS @ 1/2 + JR Z,HB_Z280BUS ; GOT IT, SHOW IT + SRL H ; DIVIDE + RR L ; ... BY 2 + CP %00000010 ; BUS @ 1/4 + JR Z,HB_Z280BUS ; GOT IT, SHOW IT + PRTS("???$") ; INVALID VALUE + JR HB_Z280BUS1 ; CONTINUE +HB_Z280BUS: + CALL PRTD3M ; PRINT AS DECIMAL WITH 3 DIGIT MANTISSA +HB_Z280BUS1: + PRTS("MHz$") ; SUFFIX +#ENDIF +; ; DISPLAY CPU CONFIG ; CALL NEWLINE + XOR A #IF (CPUFAM == CPU_Z180) LD A,Z180_MEMWAIT -#ELSE - LD A,0 +#ENDIF +#IF (CPUFAM == CPU_Z280) + LD A,Z280_MEMWAIT #ENDIF CALL PRTDECB CALL PRTSTRD .TEXT " MEM W/S, $" + LD A,1 #IF (CPUFAM == CPU_Z180) LD A,Z180_IOWAIT + 1 -#ELSE - LD A,1 +#ENDIF +#IF (CPUFAM == CPU_Z280) + LD A,Z280_IOWAIT + 1 #ENDIF CALL PRTDECB CALL PRTSTRD .TEXT " I/O W/S$" +#IF (CPUFAM == CPU_Z280) + CALL PRTSTRD + .TEXT ", $" + LD A,Z280_INTWAIT + CALL PRTDECB + CALL PRTSTRD + .TEXT " INT W/S$" +#ENDIF #IF (INTMODE > 0) CALL PRTSTRD .TEXT ", INT MODE $" LD A,INTMODE CALL PRTDECB #ENDIF +; + CALL PRTSTRD + .TEXT ", $" + CALL PRTSTRD +#IF (MEMMGR == MM_NONE) + .TEXT "NONE$" +#ENDIF +#IF (MEMMGR == MM_SBC) + .TEXT "SBC$" +#ENDIF +#IF (MEMMGR == MM_Z2) + .TEXT "Z2$" +#ENDIF +#IF (MEMMGR == MM_N8) + .TEXT "N8$" +#ENDIF +#IF (MEMMGR == MM_Z180) + .TEXT "Z180$" +#ENDIF +#IF (MEMMGR == MM_Z280) + .TEXT "Z280$" +#ENDIF +#IF (MEMMGR == MM_ZRC) + .TEXT "ZRC$" +#ENDIF + CALL PRTSTRD + .TEXT " MMU$" ; ; DISPLAY MEMORY CONFIG ; @@ -1478,6 +1908,30 @@ HB_SPDTST: CALL PRTSTRD .TEXT "KB RAM$" ; +#IF (CPUFAM == CPU_Z280) + CALL NEWLINE + PRTS("Z280: $") + PRTS("MSR=$") + LD C,Z280_MSR ; MASTER STATUS REGISTER + .DB $ED,$66 ; LDCTL HL,(C) + CALL PRTHEXWORDHL + CALL PC_SPACE + PRTS("BTCR=$") + LD C,Z280_BTCR ; BUS TIMING AND CONTROL REGISTER + .DB $ED,$66 ; LDTCL HL,(C) + CALL PRTHEXWORDHL + CALL PC_SPACE + PRTS("BTIR=$") + LD C,Z280_BTIR ; BUS TIMING AND CONTROL REGISTER + .DB $ED,$66 ; LDTCL HL,(C) + CALL PRTHEXWORDHL + CALL PC_SPACE + PRTS("CCR=$") + LD C,Z280_CCR ; CACHE CONTROL REGISTER + .DB $ED,$66 ; LDTCL HL,(C) + CALL PRTHEXWORDHL +#ENDIF +; ; LOW BATTERY DIAGNOSTIC MESSAGE ; #IF (BATCOND) @@ -1547,26 +2001,42 @@ IS_REC_M1: #ENDIF ; INITSYS3: -; CALL PRTSUM ; PRINT UNIT/DEVICE SUMMARY TABLE ; +INITSYS4: +; +#IF (MEMMGR == MM_Z280) + ; LEAVE SYSTEM MODE STACK POINTING TO AN OK PLACE + LD SP,HB_STACK ; NOW USE REAL SYSTEM STACK LOC + + HB_DI ; NOT SURE THIS IS NEEDED + + ; ACTIVATE THE CORRECT USER MODE BANK + LD A,(HB_CURBNK) ; GET CURRENT BANK + CALL HBX_BNKSEL + + ; PRESET THE USER MODE STACK + LD HL,HBX_LOC + .DB $ED,$8F ; LDCTL USP,HL + + HB_EI ; NOT SURE THIS IS NEEDED + + ; SWITCH TO USER MODE NOW + LD C,Z280_MSR + LD HL,$407F + .DB $ED,$6E ; LDCTL (C),HL +#ENDIF +; ; CHAIN TO OS LOADER ; #IFDEF ROMBOOT ; PERFORM BANK CALL TO OS IMAGES BANK IN ROM LD A,BID_IMG0 ; CHAIN TO OS IMAGES BANK - LD HL,0 ; ENTER AT ADDRESS 0 + LD IX,0 ; ENTER AT ADDRESS 0 CALL HBX_BNKCALL ; GO THERE HALT ; WE SHOULD NEVER COME BACK! #ELSE ; COPY OS IMAGE: BID_USR: --> BID_USR:0 - ;LD A,BID_USR - ;LD (HB_SRCBNK),A - ;LD (HB_DSTBNK),A - ;LD HL,HB_END - ;LD DE,0 - ;LD BC,$8000 - ;CALL HBX_BNKCPY LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY LD D,BID_USR ; D = DEST BANK = USER BANK ;LD E,BID_USR ; E = SRC BANK = USER BANK @@ -1575,13 +2045,13 @@ INITSYS3: LD HL,$8000 ; HL = COPY LEN = ENTIRE BANK RST 08 ; DO IT LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY - LD HL,HB_END ; COPY FROM END OF OF HBIOS + LD HL,HB_END ; COPY FROM END OF HBIOS LD DE,0 ; TO USER ADDRESS 0 RST 08 ; DO IT ; ; PERFORM BANK CALL TO USER BANK LD A,BID_USR ; CHAIN TO OS IMAGES BANK - LD HL,0 ; ENTER AT ADDRESS 0 + LD IX,0 ; ENTER AT ADDRESS 0 CALL HBX_BNKCALL ; GO THERE HALT ; WE SHOULD NEVER COME BACK! ; @@ -1627,6 +2097,7 @@ HB_INIT_REC: #IF (PLATFORM == PLT_SBC) .DW UART_INIT .DW MD_INIT + .DW PPIDE_INIT #ENDIF HB_INITRLEN .EQU (($ - HB_INIT_REC) / 2) ; @@ -1644,18 +2115,27 @@ HB_PCINITTBL: #IF (UARTENABLE) .DW UART_PREINIT #ENDIF +#IF (DUARTENABLE) + .DW DUART_PREINIT +#ENDIF #IF (SIOENABLE) .DW SIO_PREINIT #ENDIF #IF (ACIAENABLE) .DW ACIA_PREINIT #ENDIF +#IF (Z2UENABLE) + .DW Z2U_PREINIT +#ENDIF #IF (PIO_4P | PIO_ZP) .DW PIO_PREINIT #ENDIF #IF (UFENABLE) .DW UF_PREINIT #ENDIF +#IF (TMSENABLE) + .DW TMS_PREINIT +#ENDIF HB_PCINITTBLLEN .EQU (($ - HB_PCINITTBL) / 2) ;================================================================================================== @@ -1666,11 +2146,14 @@ HB_INITTBL: #IF (CTCENABLE) .DW CTC_INIT #ENDIF -#IF (SPKENABLE) - .DW SPK_INIT ; AUDIBLE INDICATOR OF BOOT START +#IF (AY38910ENABLE) + .DW AY38910_INIT ; AUDIBLE INDICATOR OF BOOT START #ENDIF -#IF (AYENABLE) - .DW AY_INIT ; AUDIBLE INDICATOR OF BOOT START +#IF (SN76489ENABLE) + .DW SN76489_INIT +#ENDIF +#IF (SPKENABLE) + .DW SP_INIT ; AUDIBLE INDICATOR OF BOOT START #ENDIF #IF (ASCIENABLE) .DW ASCI_INIT @@ -1678,12 +2161,18 @@ HB_INITTBL: #IF (UARTENABLE) .DW UART_INIT #ENDIF +#IF (DUARTENABLE) + .DW DUART_INIT +#ENDIF #IF (SIOENABLE) .DW SIO_INIT #ENDIF #IF (ACIAENABLE) .DW ACIA_INIT #ENDIF +#IF (Z2UENABLE) + .DW Z2U_INIT +#ENDIF #IF (DSRTCENABLE) .DW DSRTC_INIT #ENDIF @@ -1747,6 +2236,7 @@ HB_INITTBL: #IF (UFENABLE) .DW UF_INIT #ENDIF + ; HB_INITTBLLEN .EQU (($ - HB_INITTBL) / 2) ; @@ -1782,20 +2272,29 @@ IDLE: ; HB_DISPATCH: ; +#IF (MEMMGR == MM_Z280) + ; FOR Z280 MEMMGR, WE DISPATCH VIA THE Z280 SYSCALL. + ; THE SYSCALL MECHANISM WILL CLEAR INTERRUPTS. IN + ; GENERAL, INTERRUPTS ARE OK DURING API PROCESSING, + ; SO ENABLE THEM HERE. + HB_EI +#ENDIF +; +; #IF 0 ; *DEBUG* START ; - CALL HB_DISPCALL ; DO THE WORK + CALL HB_DISPATCH1 ; DO THE WORK ; ; CHECK STACK INTEGRITY PUSH AF LD A,(HB_STACK - HB_STKSIZ + $08) CP $FF - CALL NZ,PANIC + CALL SYSCHK LD A,$FF LD (HB_STACK - HB_STKSIZ + $08),A POP AF RET -HB_DISPCALL: +HB_DISPATCH1: ; #ENDIF ; *DEBUG* END ; @@ -1807,13 +2306,20 @@ HB_DISPCALL: CP BF_RTC + $10 ; $20-$2F: REAL TIME CLOCK (RTC) JP C,RTC_DISPATCH CP BF_EMU + $10 ; $30-$3F: EMULATION - CALL C,PANIC ; OBSOLETE! + JR C,HB_DISPERR CP BF_VDA + $10 ; $40-$4F: VIDEO DISPLAY ADAPTER JP C,VDA_DISPATCH + CP BF_SND + $08 ; $50-$58: SOUND DRIVERS + JP C,SND_DISPATCH CP BF_SYS ; SKIP TO BF_SYS VALUE AT $F0 - CALL C,PANIC ; PANIC IF LESS THAN BF_SYS + JR C,HB_DISPERR ; ERROR IF LESS THAN BF_SYS JP SYS_DISPATCH ; OTHERWISE SYS CALL - CALL PANIC ; THIS SHOULD NEVER BE REACHED + ; FALL THRU +; +HB_DISPERR: + CALL SYSCHK + LD A,ERR_NOFUNC + OR A RET ; ;================================================================================================== @@ -1830,7 +2336,7 @@ CIO_DISPATCH: PUSH IY ; SAVE INCOMING IY - LD IY,CIO_TBL ; POINT IY TO START OF DIO TABLE + LD IY,CIO_TBL ; POINT IY TO START OF CIO TABLE CALL HB_DISPCALL ; GO TO GENERIC API CALL CODE POP IY ; RESTORE IY @@ -1941,10 +2447,11 @@ DIO_TBL .FILL DIO_SIZ,0 ; SPACE FOR ENTRIES ; IMPLEMENTS MULTI SECTOR READS AND I/O TO/FROM ; BANKED RAM VIA BOUNCE BUFFER ; -; TOS=READ FN ADR -; HL=BUF ADR -; E=SEC COUNT -; D=BUF BANK ID +; ON ENTRY: +; TOS=READ FN ADR +; HL=BUF ADR +; E=SEC COUNT +; D=BUF BANK ID ; HB_DSKREAD: ; @@ -2170,12 +2677,14 @@ HB_IOBNK .DB 0 ; CURRENT IO BUFFER BANK ID ; RTC_DISPATCH: PUSH HL ; SAVE INCOMING HL - LD HL,(RTC_DISPADR) ; + LD HL,(RTC_DISPADR) ; EX (SP),HL RET ; RTC_DISPERR: - OR $FF + CALL SYSCHK + LD A,ERR_NOHW + OR A RET ; ; SET RTC DISPATCH ADDRESS, USED BY RTC DRIVERS DURING INIT @@ -2235,9 +2744,54 @@ VDA_SIZ .EQU VDA_MAX * 4 ; EACH ENTRY IS 4 BYTES .DB VDA_MAX ; MAX ENTRY COUNT TABLE PREFIX VDA_CNT .DB 0 ; ENTRY COUNT PREFIX VDA_TBL .FILL VDA_SIZ,0 ; SPACE FOR ENTRIES + +; ; ;================================================================================================== -; SYSTEM FUNCTION DISPATCHER +; SOUND ADAPTER DEVICE DISPATCHER +;================================================================================================== +; +; ROUTE CALL TO SPECIFIED SOUND DEVICE DRIVER +; B: FUNCTION +; C: UNIT NUMBER +; +SND_DISPATCH: + PUSH IY ; SAVE INCOMING IY + + LD IY, SND_TBL ; POINT IY TO START OF DIO TABLE + CALL HB_DISPCALL ; GO TO GENERIC API CALL CODE + + POP IY ; RESTORE IY + RET ; AND DONE +; +; ADD AN ENTRY TO THE SND UNIT TABLE (SEE HB_ADDENT FOR DETAILS) +; +SND_ADDENT: + LD HL, SND_TBL ; POINT TO SND TABLE + JP HB_ADDENT ; ... AND GO TO COMMON CODE +; +; HBIOS VIDEO DEVICE UNIT TABLE +; +; TABLE IS BUILT DYNAMICALLY BY EACH DRIVER DURING INITIALIZATION. +; THE TABLE IS PREFIXED BY TWO BYTES. TABLE - 1 CONTAINS THE CURRENT +; NUMBER OF ENTRIES. TABLE - 2 CONTAINS THE MAXIMUM NUMBER OF ENTRIES. +; TABLE - 3 CONTAINS THE NUMBER OF SND FUNCTION IDS +; EACH ENTRY IS DEFINED AS: +; +; WORD DRIVER FUNCTION TABLE ADDRESS +; WORD UNIT SPECIFIC DATA (TYPICALLY A DEVICE INSTANCE DATA ADDRESS) +; +SND_FNCNT .EQU 8 ; NUMBER OF SND FUNCS (FOR RANGE CHECK) +SND_MAX .EQU 3 ; UP TO 2 UNITS +SND_SIZ .EQU SND_MAX * 4 ; EACH ENTRY IS 4 BYTES +; + .DB SND_FNCNT ; SND FUNCTION COUNT (FOR RANGE CHECK) + .DB SND_MAX ; MAX ENTRY COUNT TABLE PREFIX +SND_CNT .DB 0 ; ENTRY COUNT PREFIX +SND_TBL .FILL SND_SIZ,0 ; SPACE FOR ENTRIES +; +;================================================================================================== +; SYSTEM FUNCTION DISPATCHER ;================================================================================================== ; ; B: FUNCTION @@ -2270,16 +2824,57 @@ SYS_DISPATCH: JP Z,SYS_POKE ; $FB DEC A JP Z,SYS_INT ; $FC - CALL PANIC ; INVALID + DEC A ; -; SOFT RESET HBIOS, RELEASE HEAP MEMORY NOT USED BY HBIOS +; RESTART SYSTEM +; SUBFUNCTION IN C ; SYS_RESET: + LD A,C ; GET REQUESTED SUB-FUNCTION + CP BF_SYSRES_INT + JR Z,SYS_RESINT + CP BF_SYSRES_WARM + JR Z,SYS_RESWARM + CP BF_SYSRES_COLD + JR Z,SYS_RESCOLD + CALL SYSCHK + LD A,ERR_NOFUNC + OR A ; SIGNAL ERROR + RET +; +; SOFT RESET HBIOS, RELEASE HEAP MEMORY NOT USED BY HBIOS +; +SYS_RESINT: LD HL,(HEAPCURB) ; GET HBIOS HEAP THRESHOLD LD (CB_HEAPTOP),HL ; RESTORE HEAP TOP XOR A RET ; +; GO BACK TO ROM BOOT LOADER +; +SYS_RESWARM: + CALL SYS_RESINT +; +#IF (MEMMGR == MM_Z280) + JP INITSYS4 +#ELSE + ; PERFORM BANK CALL TO OS IMAGES BANK IN ROM + LD SP,HBX_LOC ; STACK JUST BELOW HBIOS PROXY + LD A,BID_IMG0 ; CHAIN TO OS IMAGES BANK + LD IX,0 ; ENTER AT ADDRESS 0 + CALL HBX_BNKCALL ; GO THERE + HALT ; WE SHOULD NEVER COME BACK! +#ENDIF +; +; RESTART SYSTEM AS THOUGH POWER HAD JUST BEEN TURNED ON +; +SYS_RESCOLD: + DI + LD SP,HBX_LOC ; STACK JUST BELOW HBIOS PROXY + LD A,BID_BOOT ; BOOT BANK + LD IX,0 ; ADDRESS ZERO + CALL HB_BNKCALL ; DOES NOT RETURN +; ; GET THE CURRENT HBIOS VERSION ; ON INPUT, C=0 ; RETURNS VERSION IN DE AS BCD @@ -2296,9 +2891,24 @@ SYS_VER: ; SET ACTIVE MEMORY BANK AND RETURN PREVIOUSLY ACTIVE MEMORY BANK ; NOTE THAT IT GOES INTO EFFECT AS HBIOS FUNCTION IS EXITED ; HERE, WE JUST SET THE CURRENT BANK -; CALLER MUST EXTABLISH UPPER MEMORY STACK BEFORE INVOKING THIS FUNCTION! +; CALLER MUST ESTABLISH UPPER MEMORY STACK BEFORE INVOKING THIS FUNCTION! ; SYS_SETBNK: +#IF (MEMMGR == MM_Z280) + ; FOR Z280 MEMMGR, WE ARE IN SYSTEM MODE HERE, SO WE CAN UPDATE + ; THE USER MODE BANK WITHOUT IMPACTING THE RUNNING CODE. IT + ; TAKE EFFECT UPON RETURN TO USER MODE. + LD A,(HB_INVBNK) ; GET PREVIOUS BANK + PUSH AF ; SAVE IT + LD A,C ; NEW BANK TO A + LD (HB_INVBNK),A ; UPDATE INVBNK + LD B,$00 ; FIRST USER PDR + CALL Z280_BNKSEL ; DO IT + POP AF ; RECOVER PREV BANK + LD C,A ; PREVIOUS BANK TO C + XOR A ; SIGNAL SUCCESS + RET ; DONE +#ELSE PUSH HL ; SAVE INCOMING HL LD HL,HB_INVBNK ; POINT TO HBIOS INVOKE BANK ID ADDRESS LD A,(HL) ; GET EXISTING BANK ID TO A @@ -2307,6 +2917,7 @@ SYS_SETBNK: POP HL ; RESTORE ORIGINAL HL XOR A ; SIGNAL SUCCESS RET ; DONE +#ENDIF ; ; GET ACTIVE MEMORY BANK ; @@ -2360,8 +2971,9 @@ SYS_ALLOC: ; ALL OTHER REGISTERS PRESERVED ; SYS_FREE: - CALL PANIC ; NOT YET IMPLEMENTED - OR $FF + CALL SYSCHK ; NOT YET IMPLEMENTED + LD A,ERR_NOTIMPL ; NOT YET INMPLEMENTED + OR A ; SET FLAGS RET ; ; GET SYSTEM INFORMATION @@ -2370,24 +2982,38 @@ SYS_FREE: SYS_GET: LD A,C ; GET REQUESTED SUB-FUNCTION CP BF_SYSGET_CIOCNT - JR Z,SYS_GETCIOCNT + JP Z,SYS_GETCIOCNT + CP BF_SYSGET_CIOFN + JP Z,SYS_GETCIOFN CP BF_SYSGET_DIOCNT - JR Z,SYS_GETDIOCNT + JP Z,SYS_GETDIOCNT + CP BF_SYSGET_DIOFN + JP Z,SYS_GETDIOFN + CP BF_SYSGET_RTCCNT + JP Z,SYS_GETRTCCNT CP BF_SYSGET_VDACNT - JR Z,SYS_GETVDACNT + JP Z,SYS_GETVDACNT + CP BF_SYSGET_VDAFN + JP Z,SYS_GETVDAFN + CP BF_SYSGET_SNDCNT + JP Z, SYS_GETSNDCNT + CP BF_SYSGET_SNDFN + JP Z,SYS_GETSNDFN CP BF_SYSGET_TIMER - JR Z,SYS_GETTIMER + JP Z,SYS_GETTIMER CP BF_SYSGET_SECS - JR Z,SYS_GETSECS + JP Z,SYS_GETSECS CP BF_SYSGET_BOOTINFO - JR Z,SYS_GETBOOTINFO + JP Z,SYS_GETBOOTINFO CP BF_SYSGET_CPUINFO - JR Z,SYS_GETCPUINFO + JP Z,SYS_GETCPUINFO CP BF_SYSGET_MEMINFO - JR Z,SYS_GETMEMINFO + JP Z,SYS_GETMEMINFO CP BF_SYSGET_BNKINFO - JR Z,SYS_GETBNKINFO - OR $FF ; SIGNAL ERROR + JP Z,SYS_GETBNKINFO + CALL SYSCHK + LD A,ERR_NOFUNC ; SIGNAL ERROR + OR A ; SET FLAGS RET ; ; GET TIMER @@ -2399,6 +3025,7 @@ SYS_GETTIMER: HB_DI CALL LD32 HB_EI + LD C, TICKFREQ XOR A RET ; @@ -2414,7 +3041,7 @@ SYS_GETSECS: LD A,(HB_SECTCK) HB_EI NEG ; CONVERT DOWNCOUNTER TO UPCOUNTER - ADD A,TICKSPERSEC + ADD A,TICKFREQ LD C,A XOR A RET @@ -2478,6 +3105,26 @@ SYS_GETCIOCNT: XOR A ; SIGNALS SUCCESS RET ; +; GET SERIAL UNIT API FN ADR AND DATA ADR +; ENTRY: +; D: FUNCTION +; E: UNIT +; RETURNS: +; HL: FUNCTION ADDRESS +; DE: DATA BLOB ADDRESS +; +SYS_GETCIOFN: + BIT 7,E ; CHECK FOR SPECIAL UNIT CODE + CALL NZ,SYS_GETCIOFN1 ; IF SO, HANDLE IT + LD IY,CIO_TBL ; POINT TO UNIT TABLE + JP SYS_GETFN ; GO TO COMMON CODE +; +SYS_GETCIOFN1: + LD A,(CB_CONDEV) ; UNIT $80 -> CONSOLE UNIT + LD E,A ; REPLACE UNIT VALUE IN C + RET ; AND BACK TO REGULAR FLOW +; +; ; GET DISK UNIT COUNT ; SYS_GETDIOCNT: @@ -2486,6 +3133,30 @@ SYS_GETDIOCNT: XOR A ; SIGNALS SUCCESS RET ; +; GET DISK UNIT API FN ADR AND DATA ADR +; ENTRY: +; D: FUNCTION +; E: UNIT +; RETURNS: +; HL: FUNCTION ADDRESS +; DE: DATA BLOB ADDRESS +; +SYS_GETDIOFN: + LD IY,DIO_TBL ; POINT TO UNIT TABLE + JP SYS_GETFN ; GO TO COMMON CODE +; +; GET RTC UNIT COUNT +; +SYS_GETRTCCNT: + LD E,0 ; ASSUME 0 RTC DEVICES + LD A,(RTC_DISPACT) ; IS RTC ACTIVE? + OR A ; SET FLAGS + JR Z,SYS_GETRTCCNT1 ; IF NONE, DONE + INC E ; SET ONE DEVICE +SYS_GETRTCCNT1: + XOR A ; SIGNALS SUCCESS + RET +; ; GET VIDEO UNIT COUNT ; SYS_GETVDACNT: @@ -2494,6 +3165,57 @@ SYS_GETVDACNT: XOR A ; SIGNALS SUCCESS RET ; +; GET VIDEO UNIT API FN ADR AND DATA ADR +; ENTRY: +; D: FUNCTION +; E: UNIT +; RETURNS: +; HL: FUNCTION ADDRESS +; DE: DATA BLOB ADDRESS +; +SYS_GETVDAFN: + LD IY,VDA_TBL ; POINT TO UNIT TABLE + JP SYS_GETFN ; GO TO COMMON CODE +; +; GET SOUND UNIT COUNT +; +SYS_GETSNDCNT: + LD A,(SND_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST) + LD E,A ; PUT IT IN E + XOR A ; SIGNALS SUCCESS + RET +; +; GET SOUND UNIT API FN ADR AND DATA ADR +; ENTRY: +; D: FUNCTION +; E: UNIT +; RETURNS: +; HL: FUNCTION ADDRESS +; DE: DATA BLOB ADDRESS +; +SYS_GETSNDFN: + LD IY,SND_TBL ; POINT TO UNIT TABLE + JP SYS_GETFN ; GO TO COMMON CODE +; +; SHARED CODE TO COMPLETE A FUNCTION LOOKUP +; ENTRY: +; IY: DISPATCH FUNCTION TABLE +; D: FUNCTION ID +; E: UNIT NUMBER +; EXIT: +; HL: DRIVER FUNCTION ADDRESS +; DE: DRIVER UNIT DATA ADDRESS +; +SYS_GETFN: + LD A,D ; GET FUNC NUM FROM D + LD B,A ; AND PUT IN B + LD A,E ; GET UNIT NUM FROM E + LD C,A ; AND PUT IN C + CALL HB_DISPCALC ; CALC FN ADR & BLOB ADR + PUSH IY ; MOVE DATA ADR + POP DE ; ... TO DE + RET ; AF STILL HAS RESULT OF CALC +; ; SET SYSTEM PARAMETERS ; PARAMETER(S) TO SET INDICATED IN C ; @@ -2505,7 +3227,9 @@ SYS_SET: JR Z,SYS_SETSECS CP BF_SYSSET_BOOTINFO JR Z,SYS_SETBOOTINFO - OR $FF ; SIGNAL ERROR + CALL SYSCHK + LD A,ERR_NOFUNC ; SIGNAL ERROR + OR A ; SET FLAGS RET ; ; SET BOOT INFORMATION @@ -2554,15 +3278,30 @@ SYS_SETSECS: ; SYS_PEEK: #IF (INTMODE == 1) - LD A,I - DI + #IF (CPUFAM == CPU_Z280) + PUSH IY + LD C,Z280_MSR + .DB $FD,$ED,$66 ; LDCTL IY,(C) + PUSH IY + HB_DI + #ELSE + LD A,I ; SAVE THE INTERRUPT STATUS + DI ; COPY IFF2 TO P/V FLAG PUSH AF + #ENDIF #ENDIF CALL HBX_PEEK ; IMPLEMENTED IN PROXY #IF (INTMODE == 1) - POP AF - JP PO,$+4 - EI + #IF (CPUFAM == CPU_Z280) + LD C,Z280_MSR + POP IY + .DB $FD,$ED,$6E ; LDCTL (C),IY + POP IY + #ELSE + POP AF ; RECALL INITIAL INTERRUPT STATUS + JP PO,$+4 ; RETURN TO INITIAL STATE + HB_EI + #ENDIF #ENDIF XOR A RET @@ -2576,15 +3315,30 @@ SYS_PEEK: ; SYS_POKE: #IF (INTMODE == 1) - LD A,I - DI + #IF (CPUFAM == CPU_Z280) + PUSH IY + LD C,Z280_MSR + .DB $FD,$ED,$66 ; LDCTL IY,(C) + PUSH IY + HB_DI + #ELSE + LD A,I ; SAVE THE INTERRUPT STATUS + HB_DI ; COPY IFF2 TO P/V FLAG PUSH AF + #ENDIF #ENDIF CALL HBX_POKE ; IMPLEMENTED IN PROXY #IF (INTMODE == 1) - POP AF - JP PO,$+4 - EI + #IF (CPUFAM == CPU_Z280) + LD C,Z280_MSR + POP IY + .DB $FD,$ED,$6E ; LDCTL (C),IY + POP IY + #ELSE + POP AF ; RECALL INITIAL INTERRUPT STATUS + JP PO,$+4 ; RETURN TO INITIAL STATE + HB_EI + #ENDIF #ENDIF XOR A RET @@ -2600,7 +3354,9 @@ SYS_INT: JR Z,SYS_INTGET CP BF_SYSINT_SET JR Z,SYS_INTSET - OR $FF ; SIGNAL ERROR + CALL SYSCHK + LD A,ERR_NOFUNC ; SIGNAL ERROR + OR A ; SET FLAGS RET ; ; GET INTERRUPT SYSTEM INFORMATION @@ -2626,8 +3382,9 @@ SYS_INTINFO: ; SYS_INTVECADR: #IF (INTMODE == 0) - CALL PANIC ; INVALID FOR INT MODE 0 - OR $FF + CALL SYSCHK ; INVALID FOR INT MODE 0 + LD A,ERR_BADCFG ; SIGNAL ERROR + OR A ; SET FLAGS RET #ENDIF #IF (INTMODE == 1) @@ -2641,8 +3398,9 @@ SYS_INTVECADR: LD A,E ; INCOMING INDEX POSITION TO A CP C ; COMPARE TO VECTOR COUNT JR C,SYS_INTGET1 ; CONTINUE IF POSITION IN RANGE - CALL PANIC ; ELSE ERROR - OR $FF + CALL SYSCHK ; ELSE ERROR + LD A,ERR_RANGE ; SIGNAL ERROR + OR A ; SET FLAGS RET SYS_INTGET1: OR A ; CLEAR CARRY @@ -2737,10 +3495,65 @@ HB_IM1PTR .DW HB_IVT ; POINTER FOR NEXT IM1 ENTRY ; #ENDIF ; +; +; +#IF (MEMMGR == MM_Z280) + +Z280_TIMINT: + ; DISCARD REASON CODE + INC SP + INC SP +; + ; SAVE INCOMING REGISTERS + PUSH AF + PUSH BC + PUSH DE + PUSH HL +; + ; CALL PRIMARY TIMER LOGIC + CALL HB_TIMINT +; + ; SELECT I/O PAGE $FE + LD L,$FE ; COUNTER/TIMER I/O PAGE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; CLEAR END OF COUNT CONDITION TO RESET INTERRUPT + IN A,(Z280_CT0_CMDST) ; GET STATUS + RES 1,A ; CLEAR CC + OUT (Z280_CT0_CMDST),A ; SET C/T 0 +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; RESTORE REGISTERS + POP HL + POP DE + POP BC + POP AF +; + .DB $ED,$55 ; RETIL +; +#ENDIF +; +; +; +HB_TIMINT: +#IF 0 ; *DEBUG* + LD HL,HB_TIMDBGCNT + INC (HL) + LD A,(HL) + OUT (DIAGPORT),A + JR HB_TIMDBG1 +HB_TIMDBGCNT .DB 0 +HB_TIMDBG1: +#ENDIF ; *DEBUG* +; ; TIMER HANDLER VECTORS ; THESE CAN BE HOOKED AS DESIRED BY DRIVERS ; -HB_TIMINT: VEC_TICK: JP HB_TICK ; TICK PROCESSING VECTOR VEC_SECOND: @@ -2753,9 +3566,9 @@ HB_TICK: LD HL,HB_TICKS ; POINT TO TICK COUNTER CALL INC32HL LD HL,HB_SECTCK ; POINT TO SECONDS TICK COUNTER - DEC (HL) ; COUNTDOWN 50 TICKS + DEC (HL) ; COUNTDOWN ONE SECOND OF TICKS JR NZ,HB_TICK1 ; NOT DONE, SKIP AHEAD - LD A,TICKSPERSEC ; 50 TICKS PER SECOND + LD A,TICKFREQ ; TICKS PER SECOND LD (HL),A ; RESET COUNTDOWN REGISTER CALL VEC_SECOND ; DO SECONDS PROCESSING VIA VECTOR ; @@ -2779,7 +3592,6 @@ HB_SECOND: ; INCREMENT SECONDS COUNTER LD HL,HB_SECS ; POINT TO SECONDS COUNTER JP INC32HL ; INCREMENT AND RETURN - ; ; BAD INTERRUPT HANDLER ; @@ -2808,26 +3620,227 @@ HB_BADINTCNT .DB 0 OR $FF ; SIGNAL INTERRUPT HANDLED RET ; +; Z280 BAD INT HANDLER +; +#IF (MEMMGR == MM_Z280) +; +Z280_BADINT: + ; SAVE REASON CODE FOR POSSIBLE RETURN VIA RETIL + EX (SP),HL ; GET MSR, SAVE HL + LD (HB_RCSAV),HL ; SAVE IT + POP HL ; RECOVER HL, POP STACK + ; SAVE MSR FOR POSSIBLE RETURN VIA RETIL + EX (SP),HL ; GET MSR, SAVE HL + LD (HB_MSRSAV),HL ; SAVE IT + POP HL ; RECOVER HL, POP STACK +; + PUSH DE + LD DE,Z280_BADINTSTR + CALL NEWLINE2 + PRTS("+++ $") + CALL WRITESTR + POP DE + CALL XREGDMP +; + ; RECOVER MSR, THEN RETURN VIA RETIL + PUSH HL ; SAVE HL + LD HL,(HB_RCSAV) ; GET SAVED REASON CODE + PRTS(" RC=$") + CALL PRTHEXWORDHL ; DUMP MSR + LD HL,(HB_MSRSAV) ; GET SAVED MSR + PRTS(" MSR=$") + CALL PRTHEXWORDHL ; DUMP MSR + EX (SP),HL ; MSR TO STK, RECOVER HL +; + .DB $ED,$55 ; RETIL +; +Z280_SSTEP: + ; SAVE HL AND MSR FOR POSSIBLE RETURN VIA RETIL + EX (SP),HL ; GET MSR, SAVE HL + LD (HB_MSRSAV),HL ; SAVE IT + POP HL ; RECOVER HL, POP STACK +; + PUSH DE + LD DE,Z280_SSTEPSTR + JP Z280_DIAG +; +Z280_BRKHLT: + ; SAVE HL AND MSR FOR POSSIBLE RETURN VIA RETIL + EX (SP),HL ; GET MSR, SAVE HL + LD (HB_MSRSAV),HL ; SAVE IT + POP HL ; RECOVER HL, POP STACK +; + PUSH DE + LD DE,Z280_BRKHLTSTR + JP Z280_DIAG +; +Z280_DIVEXC: + ; SAVE HL AND MSR FOR POSSIBLE RETURN VIA RETIL + EX (SP),HL ; GET MSR, SAVE HL + LD (HB_MSRSAV),HL ; SAVE IT + POP HL ; RECOVER HL, POP STACK +; + PUSH DE + LD DE,Z280_DIVEXCSTR + JP Z280_DIAG +; +Z280_STKOVR: + ; SAVE HL AND MSR FOR POSSIBLE RETURN VIA RETIL + EX (SP),HL ; GET MSR, SAVE HL + LD (HB_MSRSAV),HL ; SAVE IT + POP HL ; RECOVER HL, POP STACK +; + PUSH DE + LD DE,Z280_STKOVRSTR + JP Z280_DIAG +; +Z280_ACCVIO: + ; SAVE HL AND MSR FOR POSSIBLE RETURN VIA RETIL + EX (SP),HL ; GET MSR, SAVE HL + LD (HB_MSRSAV),HL ; SAVE IT + POP HL ; RECOVER HL, POP STACK +; + PUSH DE + LD DE,Z280_ACCVIOSTR + JP Z280_DIAG +; +Z280_DIAG: + CALL NEWLINE2 + PRTS("+++ $") + CALL WRITESTR + POP DE + CALL XREGDMP +; + ; RECOVER MSR, THEN RETURN VIA RETIL + PUSH HL ; SAVE HL + LD HL,(HB_MSRSAV) ; GET SAVED MSR + PRTS(" MSR=$") + CALL PRTHEXWORDHL ; DUMP MSR + EX (SP),HL ; MSR TO STK, RECOVER HL +; + ;.DB $ED,$55 ; RETIL + DI + HALT +; +Z280_BADINTSTR .TEXT "BAD INT $" +Z280_SSTEPSTR .TEXT "SINGLE STEP $" +Z280_BRKHLTSTR .TEXT "BREAK HALT $" +Z280_DIVEXCSTR .TEXT "DIVISION EXCEPTION $" +Z280_STKOVRSTR .TEXT "STACK OVERFLOW $" +Z280_ACCVIOSTR .TEXT "ACCESS VIOLATION $" +; +#ENDIF +; +; Z280 PRIVILEGED INSTRUCTION HANDLER +; +#IF (MEMMGR == MM_Z280) +; +Z280_PRIVINST: + ; SAVE HL AND MSR FOR POSSIBLE RETURN VIA RETIL + EX (SP),HL ; GET MSR, SAVE HL + LD (HB_MSRSAV),HL ; SAVE IT + POP HL ; RECOVER HL, POP STACK + EX (SP),HL ; GET ADR, SAVE HL +; + PUSH AF + PUSH BC + PUSH DE +; + .DB $ED,$96 ; LDUP A,(HL) + + ;CALL PC_LBKT + ;CALL PRTHEXBYTE + ;CALL PC_RBKT +; + ; HANDLE DI + CP $F3 ; DI? + JR NZ,Z280_PRIVINST2 + HB_DI ; DO THE DI + INC HL ; BUMP PAST IT + JR Z280_PRIVINSTX +; +Z280_PRIVINST2: + ; HANDLE EI + CP $FB ; EI? + JR NZ,Z280_PRIVINST3 + HB_EI ; DO THE EI + INC HL ; BUMP PAST IT + JR Z280_PRIVINSTX +; +Z280_PRIVINST3: + ; SOMETHING ELSE, DIAGNOSE & HALT SYSTEM + LD DE,Z280_PRIVSTR + CALL WRITESTR + CALL PRTHEXWORDHL +; + ; DUMP 16 BYTES OF USER ADDRESS SPACE + CALL PC_SPACE + CALL PC_LBKT + LD B,$10 +Z280_PRIVINST4: + .DB $ED,$96 ; LDUP A,(HL) + CALL PRTHEXBYTE + INC HL + DJNZ Z280_PRIVINST4 + CALL PC_RBKT +; + ; GO NO FURTHER + DI + HALT +; +Z280_PRIVINSTX: + ; RESTORE REGISTERS + POP DE + POP BC + POP AF +; + ; RECOVER HL AND MSR, THEN RETURN VIA RETIL + EX (SP),HL ; RECOVER HL, ADR TO STK + PUSH HL ; SAVE HL + LD HL,(HB_MSRSAV) ; GET SAVED MSR + EX (SP),HL ; MSR TO STK, RECOVER HL + .DB $ED,$55 ; RETIL +; +HB_MSRSAV .DW 0 ; SAVED MSR +HB_RCSAV .DW 0 ; SAVED REASON CODE +; +Z280_PRIVSTR .TEXT "\r\n\r\n*** Privileged Instruction @$" +; +#ENDIF +; ; COMMON API FUNCTION DISPATCH CODE ; -; ON ENTRY C IS UNIT # (INDEX INTO XXX_TBL OF UNITS) -; AND IY POINTS TO START OF UNIT TABLE. +; ON ENTRY B IS API FUNCTION NUMBER AND C IS UNIT # +; (INDEX INTO XXX_TBL OF UNITS) AND IY POINTS TO START OF UNIT TABLE. ; USE UNIT # IN C TO LOOKUP XXX_TBL ENTRY. THE XXX_TBL ; ENTRY CONTAINS THE START OF THE DRIVER FUNCTION TABLE AND ; THE DEVICE SPECIFIC INSTANCE DATA (BLOB). SET IY TO BLOB ADDRESS ; AND CALL THE SPECIFIC FUNCTION REQUESTED IN THE DRIVER. ; HB_DISPCALL: - ; CHECK INCOMING UNIT INDEX IN C FOR VAILIDITY + PUSH HL ; SAVE INCOMING HL VALUE + CALL HB_DISPCALC ; IY = BLOB ADR, HL = FN ADR + JR NZ,HB_DISPCALL1 ; ABORT ON ERROR + EX (SP),HL ; RESTORE HL & FN ADR TO TOS + RET ; JUMP TO FN ADR +HB_DISPCALL1: + POP HL ; RECOVER HL + RET ; AND DONE +; +; ENTRY: BC=FUNC/UNIT, IY=DISPATCH TABLE +; EXIT: HL=FUNC ADR, IY=DATA BLOB ADR +; +HB_DISPCALC: + ; CHECK INCOMING UNIT INDEX IN C FOR VALIDITY LD A,C ; A := INCOMING DISK UNIT INDEX CP (IY-1) ; COMPARE TO COUNT - JR NC,HB_DISPERR ; HANDLE INVALID UNIT INDEX + JR NC,HB_UNITERR ; HANDLE INVALID UNIT INDEX ; CHECK FUNCTION INDEX FOR VALIDITY LD A,B ; A := INCOMING FUNCTION NUMBER AND $0F ; LOW NIBBLE ONLY FOR FUNC INDEX CP (IY-3) ; CHECK FN NUM AGAINST MAX - JR NC,HB_DISPERR ; HANDLE FN NUM OUT OF RANGE ERROR + JR NC,HB_FUNCERR ; HANDLE FN NUM OUT OF RANGE ERROR ; BUMP IY TO ACTUAL XXX_TBL ENTRY FOR INCOMING UNIT INDEX PUSH BC ; SAVE BC @@ -2838,7 +3851,7 @@ HB_DISPCALL: POP BC ; RESTORE BC ; DERIVE DRIVER FUNC ADR TO CALL - PUSH HL ; SAVE INCOMING HL + ;PUSH HL ; SAVE INCOMING HL LD L,(IY+0) ; COPY DRIVER FUNC TABLE LD H,(IY+1) ; ... START TO HL RLCA ; CONV UNIT (STILL IN A) TO FN ADR OFFSET @@ -2847,21 +3860,30 @@ HB_DISPCALL: INC HL ; ... TO GET LD H,(HL) ; ... ACTUAL LD L,A ; ... TARGET FUNCTION ADDRESS - EX (SP),HL ; RESTORE HL, FUNC ADR ON STACK + ;EX (SP),HL ; RESTORE HL, FUNC ADR ON STACK ; GET UNIT INSTANCE DATA BLOB ADDRESS TO IY - PUSH HL ; SAVE INCOMING HL + ;PUSH HL ; SAVE INCOMING HL + PUSH HL ; SAVE FUNC ADR LD L,(IY+2) ; HL := DATA BLOB ADDRESS LD H,(IY+3) ; ... EX (SP),HL ; RESTORE HL, BLOB ADR ON TOS POP IY ; IY := BLOB ADR + XOR A ; SIGNAL SUCCESS RET ; JUMP TO DRIVER FUNC ADR ON TOS ; -HB_DISPERR: - CALL PANIC ; PANIC - OR $FF ; SIGNAL ERROR - RET ; AND RETURN VIA DISPEXIT +HB_FUNCERR: + CALL SYSCHK + LD A,ERR_NOFUNC ; SIGNAL ERROR + OR A ; SET FLAGS + RET +; +HB_UNITERR: + CALL SYSCHK + LD A,ERR_NOUNIT ; SIGNAL ERROR + OR A ; SET FLAGS + RET ; ; ADD AN ENTRY TO THE UNIT TABLE AT ADDRESS IN HL ; BC: DRIVER FUNCTION TABLE @@ -2947,13 +3969,649 @@ HB_ALLOC: HB_ALLOC1: ; ERROR RETURN POP DE ; RESTORE INCOMING DE - OR $FF ; SIGNAL ERROR - RET ; AND RETURN + CALL SYSCHK + LD A,ERR_NOMEM ; SIGNAL ERROR + OR A ; SET FLAGS + RET ; HB_TMPSZ .DW 0 HB_TMPREF .DW 0 ; ;================================================================================================== +; Z280 INTERRUPT VECTOR TABLE +;================================================================================================== +; +#IF (MEMMGR == MM_Z280) +; + ; THE Z280 IVT MUST BE ON A 4K BOUNDARY. IT HAS BEEN LOCATED + ; HERE IN AN EFFORT TO MINIMIZE WASTED SPACE. THERE SHOULD BE + ; A LITTLE LESS THAN 4K OF CODE ABOVE. +; + .FILL $1000 - ($ & $FFF) ; MUST BE 4K ALIGNED! +; +Z280_IVT: + .DW 0, 0 ; RESERVED + .DW 0 ; NMI MSR + .DW 0 ; NMI VECTOR + .DW $0000 ; INT A MSR + .DW Z280_BADINT ; INT A VECTOR + .DW $0000 ; INT B MSR + .DW Z280_BADINT ; INT B VECTOR + .DW $0000 ; INT C MSR + .DW Z280_BADINT ; INT C VECTOR + .DW $0000 ; COUNTER/TIMER 0 MSR + .DW Z280_BADINT ; COUNTER/TIMER 0 VECTOR + .DW $0000 ; COUNTER/TIMER 1 MSR + .DW Z280_BADINT ; COUNTER/TIMER 1 VECTOR + .DW 0, 0 ; RESERVED + .DW $0000 ; COUNTER/TIMER 2 MSR + .DW Z280_BADINT ; COUNTER/TIMER 2 VECTOR + .DW $0000 ; DMA CHANNEL 0 MSR + .DW Z280_BADINT ; DMA CHANNEL 0 VECTOR + .DW $0000 ; DMA CHANNEL 1 MSR + .DW Z280_BADINT ; DMA CHANNEL 1 VECTOR + .DW $0000 ; DMA CHANNEL 2 MSR + .DW Z280_BADINT ; DMA CHANNEL 2 VECTOR + .DW $0000 ; DMA CHANNEL 3 MSR + .DW Z280_BADINT ; DMA CHANNEL 3 VECTOR + .DW $0000 ; UART RECEIVER MSR + .DW Z280_BADINT ; UART RECEIVER VECTOR + .DW $0000 ; UART TRANSMITTER MSR + .DW Z280_BADINT ; UART TRANSMITTER VECTOR + .DW $0000 ; SINGLE STEP TRAP MSR + .DW Z280_SSTEP ; SINGLE STEP TRAP VECTOR + .DW $0000 ; BREAK ON HALT TRAP MSR + .DW Z280_BRKHLT ; BREAK ON HALT TRAP VECTOR + .DW $0000 ; DIVISION EXCEPTION TRAP MSR + .DW Z280_DIVEXC ; DIVISION EXCEPTION TRAP VECTOR + .DW $0000 ; STACK OVERFLOW WARNING TRAP MSR + .DW Z280_STKOVR ; STACK OVERFLOW WARNING TRAP VECTOR + .DW $0000 ; ACCESS VIOLATION TRAP MSR + .DW Z280_ACCVIO ; ACCESS VIOLATION TRAP VECTOR + .DW $0000 ; SYSTEM CALL TRAP MSR + .DW Z280_SYSCALL ; SYSTEM CALL TRAP VECTOR + .DW $0000 ; PRIVILEGED INSTRUCTION TRAP MSR + .DW Z280_PRIVINST ; PRIVILEGED INSTRUCTION TRAP VECTOR + .DW $0000 ; EPU <- MEMORY EXTENDED INSTRUCTION TRAP MSR + .DW $0000 ; EPU <- MEMORY EXTENDED INSTRUCTION TRAP VECTOR + .DW $0000 ; MEMORY <- EPU EXTENDED INSTRUCTION TRAP MSR + .DW $0000 ; MEMORY <- EPU EXTENDED INSTRUCTION TRAP VECTOR + .DW $0000 ; A <- EPU EXTENDED INSTRUCTION TRAP MSR + .DW $0000 ; A <- EPU EXTENDED INSTRUCTION TRAP VECTOR + .DW $0000 ; EPU INTERNAL OPERATION EXTENDED INSTRUCTION TRAP MSR + .DW $0000 ; EPU INTERNAL OPERATION EXTENDED INSTRUCTION TRAP VECTOR + .DW 0, 0 ; RESERVED + .DW 0, 0 ; RESERVED + ; PROGRAM COUNTER VALUES FOR NMI/INTA (16) + .DW HBX_IV00 + .DW HBX_IV01 + .DW HBX_IV02 + .DW HBX_IV03 + .DW HBX_IV04 + .DW HBX_IV05 + .DW HBX_IV06 + .DW HBX_IV07 + .DW HBX_IV08 + .DW HBX_IV09 + .DW HBX_IV0A + .DW HBX_IV0B + .DW HBX_IV0C + .DW HBX_IV0D + .DW HBX_IV0E + .DW HBX_IV0F + ; THE REMAINDER OF THE Z280 IVT IS TRUNCATED HERE BECAUSE IT + ; TAKES A BUNCH OF SPACE AND IS NOT USED. WE SUPPORT ONLY + ; 16 VECTORED INTERRUPTS AND THEY MUST BE CONNECTED TO INTA. +; +#ENDIF +; +; Z280 BANK SELECTION (CALLED FROM PROXY) +; +; THIS VERSION USES A MASSIVE (512 BYTE) TABLE TO OPTIMIZE THE +; SPEED OF THE BANK SWITCH. BY USING THE TABLE, IT IS POSSIBLE +; EXECUTE THE CORE OF THE BANKSWITCH WITH A SINGLE OTIRW. +; +#IF (MEMMGR == MM_Z280) & FALSE +; +; REG A HAS BANK ID, REG B HAS INITIAL PDR TO PROGRAM +; REGISTERS AF, BC, HL DESTROYED +; +Z280_BNKSEL: +; + ; SELECT I/O PAGE FOR MMU + LD L,$FF ; MMU AT I/O PAGE $FF + LD C,Z280_IOPR ; I/O PAGE REGISTER TO C + .DB $ED,$6E ; LDCTL (C),HL +; + ; POINT HL TO STARTING ENTRY TO PROGRAM. + ; OPTIMIZED TO ASSUME HL IS PAGE ALIGNED! + LD H,Z280_PDRTBL >> 8 + SLA A + JR NC,Z280_BNKSEL1 + INC H +Z280_BNKSEL1: + RLCA + RLCA + RLCA + LD L,A +; +Z280_BNKSEL2: + ; POINT TO FIRST PDR TO PROGRAM + LD A,B ; FIRST PDR TO PROG + OUT (Z280_MMUPDRPTR),A ; SET THE PDR POINTER +; + ; PROGRAM 8 PDRS + LD C,Z280_MMUBLKMOV ; PDR BLOCK MOVE PORT + LD B,8 ; PROGRAM 8 PDRS + .DB $ED,$93 ; OTIRW +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O PAGE $00 + LD C,Z280_IOPR ; I/O PAGE REGISTER TO C + .DB $ED,$6E ; LDCTL (C),HL +; + RET +; +#IF (($ & $FF) != 0) + ; PAGE ALIGN THE TABLE + .FILL $100 - ($ & $FF) +#ENDIF +; +#IF (($ % 2) == 1) + ; WORD ALIGN THE TABLE + .DB 0 +#ENDIF +; +Z280_PDRTBL: + ; BANK $00 + .DW ($000 << 4) | $A + .DW ($001 << 4) | $A + .DW ($002 << 4) | $A + .DW ($003 << 4) | $A + .DW ($004 << 4) | $A + .DW ($005 << 4) | $A + .DW ($006 << 4) | $A + .DW ($007 << 4) | $A + ; BANK $01 + .DW ($008 << 4) | $A + .DW ($009 << 4) | $A + .DW ($00A << 4) | $A + .DW ($00B << 4) | $A + .DW ($00C << 4) | $A + .DW ($00D << 4) | $A + .DW ($00E << 4) | $A + .DW ($00F << 4) | $A + ; BANK $02 + .DW ($010 << 4) | $A + .DW ($011 << 4) | $A + .DW ($012 << 4) | $A + .DW ($013 << 4) | $A + .DW ($014 << 4) | $A + .DW ($015 << 4) | $A + .DW ($016 << 4) | $A + .DW ($017 << 4) | $A + ; BANK $03 + .DW ($018 << 4) | $A + .DW ($019 << 4) | $A + .DW ($01A << 4) | $A + .DW ($01B << 4) | $A + .DW ($01C << 4) | $A + .DW ($01D << 4) | $A + .DW ($01E << 4) | $A + .DW ($01F << 4) | $A + ; BANK $04 + .DW ($020 << 4) | $A + .DW ($021 << 4) | $A + .DW ($022 << 4) | $A + .DW ($023 << 4) | $A + .DW ($024 << 4) | $A + .DW ($025 << 4) | $A + .DW ($026 << 4) | $A + .DW ($027 << 4) | $A + ; BANK $05 + .DW ($028 << 4) | $A + .DW ($029 << 4) | $A + .DW ($02A << 4) | $A + .DW ($02B << 4) | $A + .DW ($02C << 4) | $A + .DW ($02D << 4) | $A + .DW ($02E << 4) | $A + .DW ($02F << 4) | $A + ; BANK $06 + .DW ($030 << 4) | $A + .DW ($031 << 4) | $A + .DW ($032 << 4) | $A + .DW ($033 << 4) | $A + .DW ($034 << 4) | $A + .DW ($035 << 4) | $A + .DW ($036 << 4) | $A + .DW ($037 << 4) | $A + ; BANK $07 + .DW ($038 << 4) | $A + .DW ($039 << 4) | $A + .DW ($03A << 4) | $A + .DW ($03B << 4) | $A + .DW ($03C << 4) | $A + .DW ($03D << 4) | $A + .DW ($03E << 4) | $A + .DW ($03F << 4) | $A + ; BANK $08 + .DW ($040 << 4) | $A + .DW ($041 << 4) | $A + .DW ($042 << 4) | $A + .DW ($043 << 4) | $A + .DW ($044 << 4) | $A + .DW ($045 << 4) | $A + .DW ($046 << 4) | $A + .DW ($047 << 4) | $A + ; BANK $09 + .DW ($048 << 4) | $A + .DW ($049 << 4) | $A + .DW ($04A << 4) | $A + .DW ($04B << 4) | $A + .DW ($04C << 4) | $A + .DW ($04D << 4) | $A + .DW ($04E << 4) | $A + .DW ($04F << 4) | $A + ; BANK $0A + .DW ($050 << 4) | $A + .DW ($051 << 4) | $A + .DW ($052 << 4) | $A + .DW ($053 << 4) | $A + .DW ($054 << 4) | $A + .DW ($055 << 4) | $A + .DW ($056 << 4) | $A + .DW ($057 << 4) | $A + ; BANK $0B + .DW ($058 << 4) | $A + .DW ($059 << 4) | $A + .DW ($05A << 4) | $A + .DW ($05B << 4) | $A + .DW ($05C << 4) | $A + .DW ($05D << 4) | $A + .DW ($05E << 4) | $A + .DW ($05F << 4) | $A + ; BANK $0C + .DW ($060 << 4) | $A + .DW ($061 << 4) | $A + .DW ($062 << 4) | $A + .DW ($063 << 4) | $A + .DW ($064 << 4) | $A + .DW ($065 << 4) | $A + .DW ($066 << 4) | $A + .DW ($067 << 4) | $A + ; BANK $0D + .DW ($068 << 4) | $A + .DW ($069 << 4) | $A + .DW ($06A << 4) | $A + .DW ($06B << 4) | $A + .DW ($06C << 4) | $A + .DW ($06D << 4) | $A + .DW ($06E << 4) | $A + .DW ($06F << 4) | $A + ; BANK $0E + .DW ($070 << 4) | $A + .DW ($071 << 4) | $A + .DW ($072 << 4) | $A + .DW ($073 << 4) | $A + .DW ($074 << 4) | $A + .DW ($075 << 4) | $A + .DW ($076 << 4) | $A + .DW ($077 << 4) | $A + ; BANK $0F + .DW ($078 << 4) | $A + .DW ($079 << 4) | $A + .DW ($07A << 4) | $A + .DW ($07B << 4) | $A + .DW ($07C << 4) | $A + .DW ($07D << 4) | $A + .DW ($07E << 4) | $A + .DW ($07F << 4) | $A + + ; BANK $10 + .DW ($080 << 4) | $A + .DW ($081 << 4) | $A + .DW ($082 << 4) | $A + .DW ($083 << 4) | $A + .DW ($084 << 4) | $A + .DW ($085 << 4) | $A + .DW ($086 << 4) | $A + .DW ($087 << 4) | $A + ; BANK $11 + .DW ($088 << 4) | $A + .DW ($089 << 4) | $A + .DW ($08A << 4) | $A + .DW ($08B << 4) | $A + .DW ($08C << 4) | $A + .DW ($08D << 4) | $A + .DW ($08E << 4) | $A + .DW ($08F << 4) | $A + ; BANK $12 + .DW ($090 << 4) | $A + .DW ($091 << 4) | $A + .DW ($092 << 4) | $A + .DW ($093 << 4) | $A + .DW ($094 << 4) | $A + .DW ($095 << 4) | $A + .DW ($096 << 4) | $A + .DW ($097 << 4) | $A + ; BANK $13 + .DW ($098 << 4) | $A + .DW ($099 << 4) | $A + .DW ($09A << 4) | $A + .DW ($09B << 4) | $A + .DW ($09C << 4) | $A + .DW ($09D << 4) | $A + .DW ($09E << 4) | $A + .DW ($09F << 4) | $A + ; BANK $14 + .DW ($0A0 << 4) | $A + .DW ($0A1 << 4) | $A + .DW ($0A2 << 4) | $A + .DW ($0A3 << 4) | $A + .DW ($0A4 << 4) | $A + .DW ($0A5 << 4) | $A + .DW ($0A6 << 4) | $A + .DW ($0A7 << 4) | $A + ; BANK $15 + .DW ($0A8 << 4) | $A + .DW ($0A9 << 4) | $A + .DW ($0AA << 4) | $A + .DW ($0AB << 4) | $A + .DW ($0AC << 4) | $A + .DW ($0AD << 4) | $A + .DW ($0AE << 4) | $A + .DW ($0AF << 4) | $A + ; BANK $16 + .DW ($0B0 << 4) | $A + .DW ($0B1 << 4) | $A + .DW ($0B2 << 4) | $A + .DW ($0B3 << 4) | $A + .DW ($0B4 << 4) | $A + .DW ($0B5 << 4) | $A + .DW ($0B6 << 4) | $A + .DW ($0B7 << 4) | $A + ; BANK $17 + .DW ($0B8 << 4) | $A + .DW ($0B9 << 4) | $A + .DW ($0BA << 4) | $A + .DW ($0BB << 4) | $A + .DW ($0BC << 4) | $A + .DW ($0BD << 4) | $A + .DW ($0BE << 4) | $A + .DW ($0BF << 4) | $A + ; BANK $18 + .DW ($0C0 << 4) | $A + .DW ($0C1 << 4) | $A + .DW ($0C2 << 4) | $A + .DW ($0C3 << 4) | $A + .DW ($0C4 << 4) | $A + .DW ($0C5 << 4) | $A + .DW ($0C6 << 4) | $A + .DW ($0C7 << 4) | $A + ; BANK $19 + .DW ($0C8 << 4) | $A + .DW ($0C9 << 4) | $A + .DW ($0CA << 4) | $A + .DW ($0CB << 4) | $A + .DW ($0CC << 4) | $A + .DW ($0CD << 4) | $A + .DW ($0CE << 4) | $A + .DW ($0CF << 4) | $A + ; BANK $1A + .DW ($0D0 << 4) | $A + .DW ($0D1 << 4) | $A + .DW ($0D2 << 4) | $A + .DW ($0D3 << 4) | $A + .DW ($0D4 << 4) | $A + .DW ($0D5 << 4) | $A + .DW ($0D6 << 4) | $A + .DW ($0D7 << 4) | $A + ; BANK $1B + .DW ($0D8 << 4) | $A + .DW ($0D9 << 4) | $A + .DW ($0DA << 4) | $A + .DW ($0DB << 4) | $A + .DW ($0DC << 4) | $A + .DW ($0DD << 4) | $A + .DW ($0DE << 4) | $A + .DW ($0DF << 4) | $A + ; BANK $1C + .DW ($0E0 << 4) | $A + .DW ($0E1 << 4) | $A + .DW ($0E2 << 4) | $A + .DW ($0E3 << 4) | $A + .DW ($0E4 << 4) | $A + .DW ($0E5 << 4) | $A + .DW ($0E6 << 4) | $A + .DW ($0E7 << 4) | $A + ; BANK $1D + .DW ($0E8 << 4) | $A + .DW ($0E9 << 4) | $A + .DW ($0EA << 4) | $A + .DW ($0EB << 4) | $A + .DW ($0EC << 4) | $A + .DW ($0ED << 4) | $A + .DW ($0EE << 4) | $A + .DW ($0EF << 4) | $A + ; BANK $1E + .DW ($0F0 << 4) | $A + .DW ($0F1 << 4) | $A + .DW ($0F2 << 4) | $A + .DW ($0F3 << 4) | $A + .DW ($0F4 << 4) | $A + .DW ($0F5 << 4) | $A + .DW ($0F6 << 4) | $A + .DW ($0F7 << 4) | $A + ; BANK $1F + .DW ($0F8 << 4) | $A + .DW ($0F9 << 4) | $A + .DW ($0FA << 4) | $A + .DW ($0FB << 4) | $A + .DW ($0FC << 4) | $A + .DW ($0FD << 4) | $A + .DW ($0FE << 4) | $A + .DW ($0FF << 4) | $A +; +#ENDIF +; +; Z280 BANK SELECTION (CALLED FROM PROXY) +; +; THIS VERSION IS SLOWER, BUT AVOIDS THE USE OF THE 512+ +; BYTE TABLE. +; +#IF (MEMMGR == MM_Z280) +; +; REG A HAS BANK ID, REG B HAS INITIAL PDR TO PROGRAM +; REGISTERS AF, BC, HL DESTROYED +; +Z280_BNKSEL: + ; SELECT I/O PAGE FOR MMU + LD L,$FF ; MMU AT I/O PAGE $FF + LD C,Z280_IOPR ; I/O PAGE REGISTER TO C + .DB $ED,$6E ; LDCTL (C),HL +; + ; CONVERT BANK ID TO TOP 12 BITS OF PHYSICAL ADDRESS + ; WITH $0A IN THE LOW ORDER NIBBLE: + ; BANK ID: R000 BBBB + ; PDR: 0000 RBBB B000 1010 +; + ; IF R BIT (RAM/ROM) IS SET, WE WANT TO CONVERT + ; FROM R000 BBBB -> 000R BBBB + RLCA ; A=R 000B BBBR + JP NC,Z280_BNKSEL1 + XOR %00100001 ; A=00RB BBB0 +; +Z280_BNKSEL1: + ;MULTU A,$40 ; HL=0000 RBBB B000 0000 + .DB $FD,$ED,$F9,$40 ; MULTU A,$40 +; + LD A,$0A ; VALUE FOR LOW NIBBLE + .DB $ED,$6D ; ADD HL,A ; HL=0000 RBBB B000 1010 +; +Z280_BNKSEL2: + ; POINT TO FIRST PDR TO PROGRAM + LD A,B ; INITIAL PDR TO PROG + OUT (Z280_MMUPDRPTR),A ; SET THE PDR POINTER +; + ; PROGRAM 8 PDRS + LD C,Z280_MMUBLKMOV ; PDR BLOCK MOVE PORT + ;LD B,8 ; PROGRAM 8 PDRS + LD A,$10 ; PDR VALUE INCREMENT +Z280_BNKSEL3: + ; PROGRAM 8 PDR VALUES + ; LOOP UNROLLED FOR SPEED + .DB $ED,$BF ; OUTW (C),HL + .DB $ED,$6D ; ADD HL, A ; BUMP VALUE + .DB $ED,$BF ; OUTW (C),HL + .DB $ED,$6D ; ADD HL, A ; BUMP VALUE + .DB $ED,$BF ; OUTW (C),HL + .DB $ED,$6D ; ADD HL, A ; BUMP VALUE + .DB $ED,$BF ; OUTW (C),HL + .DB $ED,$6D ; ADD HL, A ; BUMP VALUE + .DB $ED,$BF ; OUTW (C),HL + .DB $ED,$6D ; ADD HL, A ; BUMP VALUE + .DB $ED,$BF ; OUTW (C),HL + .DB $ED,$6D ; ADD HL, A ; BUMP VALUE + .DB $ED,$BF ; OUTW (C),HL + .DB $ED,$6D ; ADD HL, A ; BUMP VALUE + .DB $ED,$BF ; OUTW (C),HL + .DB $ED,$6D ; ADD HL, A ; BUMP VALUE + ;DJNZ Z280_BNKSEL3 ; DO ALL PDRS +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O PAGE $00 + LD C,Z280_IOPR ; I/O PAGE REGISTER TO C + .DB $ED,$6E ; LDCTL (C),HL +; + RET +#ENDIF +; +; Z280 BANK COPY (CALLED FROM PROXY) +; +#IF (MEMMGR == MM_Z280) +; +Z280_BNKCPY: + ; Z280 MEMORY TO MEMORY DMA + ; USE FLOW THROUGH MODE + ; SINGLE BYTE TRANSFER + ; TRANSACTION DESCRIPTION REGISTER (TDR) + ; %0000 0000 0000 0000 + ; - AUTO INCREMENT MEMORY + ; - FLOWTHROUGH OPERATION + ; - SINGLE TRANSACTION (CAN WE USE CONTINUOUS???) + ; - 1 BYTE XFER SIZE + + PUSH HL + PUSH DE + PUSH BC + + PUSH BC ; SAVE COUNT + PUSH HL ; SAVE SOURCE ADDRESS + + ; SELECT I/O PAGE $FF + LD L,$FF ; I/O PAGE $FF + LD C,Z280_IOPR ; I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL + + LD C,Z280_DMA0_DSTL ; START WITH DEST REG LO + + LD A,(HB_DSTBNK) ; DEST BANK TO ACCUM + CALL Z2DMAADR ; SETUP DEST ADR REGS + + POP DE ; SRC ADR TO DE + LD A,(HB_SRCBNK) ; DEST BANK TO ACCUM + CALL Z2DMAADR ; SETUP SOURCE ADR REGS + + POP HL ; COUNT TO HL + .DB $ED,$BF ; OUTW (C),HL + INC C ; BUMP TO TDR + + LD HL,$8000 ; ENABLE DMA0 TO RUN! + .DB $ED,$BF ; OUTW (C),HL + + ; WAIT FOR XFER TO COMPLETE +Z2DMALOOP: + .DB $ED,$B7 ; INW HL,(C) + BIT 7,H ; CHECK EN BIT OF TDR + JR NZ,Z2DMALOOP ; LOOP WHILE ACTIVE + + ; RETURN TO I/O PAGE $00 + LD L,$00 ; RESTORE I/O PAGE REG TO 0 + LD C,Z280_IOPR ; I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL + + ; SETUP RETURN VALUES + POP BC ; RECOVER ORIGINAL BC + POP DE ; RECOVER ORIGINAL DE + POP HL ; RECOVER ORIGINAL HL + ADD HL,BC ; INCREMENT SRC ADR BY COUNT + EX DE,HL ; SWAP + ADD HL,BC ; INCREMENT DST ADR BY COUNT + EX DE,HL ; SWAP BACK + LD BC,0 ; COUNT IS NOW ZERO + + RET + +Z2DMAADR: + ; SET ADDRESS REGISTERS, BANK IN A, ADDRESS IN DE + ; C POINTS TO FIRST DMA ADR PORT TO SET + BIT 7,D ; HIGH RAM? + JR Z,Z2DMAADR0 ; NO, SKIP + LD A,$8F ; SUBSTITUTE COMMON RAM BANK ID + +Z2DMAADR0: + BIT 7,A ; RAM? + JR Z,Z2DMAADR1 ; NO, SKIP + RES 7,A ; CLEAR RAM BIT + SET 4,A ; SET BIT FOR 512K OFFSET + +Z2DMAADR1: + ; ADR HI FROM A:DE + LD L,D ; L=XAAA AAAA + LD H,A ; H=BBBB BBBB + SLA L ; L=AAAA AAA0 + SRL H ; H=0BBB BBBB B + RR L ; L=BAAA AAAA + LD A,$0F ; A=0000 1111 + OR L ; A=BAAA 1111 + LD L,A ; L=BAAA 1111 + PUSH HL ; SAVE IT FOR NOW + + ; ADR LO FROM DE: + LD L,E ; L= AAAA AAAA + LD A,$F0 ; A= 1111 0000 + OR D ; A= 1111 AAAA + LD H,A ; HL=1111 AAAA AAAA AAAA + + ; SET ADR LO REG + .DB $ED,$BF ; OUTW (C),HL + INC C ; BUMP TO ADR HI REG + + ; SET ADR HI REG + POP HL ; RECOVER THE HI VAL + + .DB $ED,$BF ; OUTW (C),HL + INC C ; BUMP TO NEXT REG + + RET +#ENDIF +; +; Z280 SYSCALL VECTOR ENTRY POINT. TAKES STACK PARAMETER AS A BRANCH +; ADDRESS AND CALLS IT. ALLOWS ANY USER MODE CODE TO CALL INTO AN +; ARBITRARY LOCATION OF SYSTEM MODE CODE. +; +#IF (MEMMGR == MM_Z280) +Z280_SYSCALL: + EX (SP),HL + LD (Z280_SYSCALL_GO+1),HL + POP HL +Z280_SYSCALL_GO: + CALL $FFFF ; PARM SET ABOVE + .DB $ED,$55 ; RETIL +#ENDIF +; +;================================================================================================== ; DEVICE DRIVERS ;================================================================================================== ; @@ -3010,6 +4668,15 @@ SIZ_UART .EQU $ - ORG_UART .ECHO " bytes.\n" #ENDIF ; +#IF (DUARTENABLE) +ORG_DUART .EQU $ + #INCLUDE "duart.asm" +SIZ_DUART .EQU $ - ORG_DUART + .ECHO "DUART occupies " + .ECHO SIZ_DUART + .ECHO " bytes.\n" +#ENDIF +; #IF (SIOENABLE) ORG_SIO .EQU $ #INCLUDE "sio.asm" @@ -3028,6 +4695,15 @@ SIZ_ACIA .EQU $ - ORG_ACIA .ECHO " bytes.\n" #ENDIF ; +#IF (Z2UENABLE) +ORG_Z2U .EQU $ + #INCLUDE "z2u.asm" +SIZ_Z2U .EQU $ - ORG_Z2U + .ECHO "Z2U occupies " + .ECHO SIZ_Z2U + .ECHO " bytes.\n" +#ENDIF +; #IF (VGAENABLE) ORG_VGA .EQU $ #INCLUDE "vga.asm" @@ -3232,15 +4908,6 @@ SIZ_SPK .EQU $ - ORG_SPK .ECHO " bytes.\n" #ENDIF ; -#IF (AYENABLE) -ORG_AY .EQU $ - #INCLUDE "ay.asm" -SIZ_AY .EQU $ - ORG_AY - .ECHO "AY occupies " - .ECHO SIZ_AY - .ECHO " bytes.\n" -#ENDIF -; #IF (PIO_4P | PIO_ZP | PPI_SBC) ORG_PIO .EQU $ #INCLUDE "pio.asm" @@ -3266,6 +4933,22 @@ SIZ_CTC .EQU $ - ORG_CTC .ECHO SIZ_CTC .ECHO " bytes.\n" #ENDIF +#IF (SN76489ENABLE) +ORG_SN76489 .EQU $ + #INCLUDE "sn76489.asm" +SIZ_SN76489 .EQU $ - ORG_SN76489 + .ECHO "SN76489 occupies " + .ECHO SIZ_SN76489 + .ECHO " bytes.\n" +#ENDIF +#IF (AY38910ENABLE) +ORG_AY38910 .EQU $ + #INCLUDE "ay38910.asm" +SIZ_AY38910 .EQU $ - ORG_AY38910 + .ECHO "AY38910 occupies " + .ECHO SIZ_AY38910 + .ECHO " bytes.\n" +#ENDIF ; #DEFINE USEDELAY #INCLUDE "util.asm" @@ -3296,21 +4979,21 @@ SIZ_CTC .EQU $ - ORG_CTC ; HB_CPUSPD: ; -#IF (DSRTCENABLE) +#IF (DSRTCENABLE & ((CPUFAM == CPU_Z80) | (CPUFAM == CPU_Z180))) ; LD A,(DSRTC_STAT) ; GET RTC STATUS OR A ; SET FLAGS RET NZ ; NOT ZERO IS ERROR ; HB_CPUSPD1: -#IF (CPUFAM == CPU_Z180) + #IF (CPUFAM == CPU_Z180) ; USE MEM W/S = 2 AND I/O W/S = 3 FOR TEST IN0 A,(Z180_DCNTL) PUSH AF LD A,$B0 ;LD A,$F0 OUT0 (Z180_DCNTL),A -#ENDIF + #ENDIF ; WAIT FOR AN INITIAL TICK TO ALIGN, THEN WAIT ; FOR SECOND TICK AND TO GET A FULL ONE SECOND LOOP COUNT @@ -3320,11 +5003,11 @@ HB_CPUSPD1: LD (HB_CURSEC),A ; SAVE NEW VALUE CALL HB_WAITSEC ; WAIT FOR SECONDS TICK ; -#IF (CPUFAM == CPU_Z180) + #IF (CPUFAM == CPU_Z180) ; RESTORE W/S SETTINGS FROM BEFORE TEST POP AF OUT0 (Z180_DCNTL),A -#ENDIF + #ENDIF ; LD A,H OR L @@ -3355,7 +5038,7 @@ HB_WAITSEC: LD DE,0 ; INIT LOOP COUNTER HB_WAITSEC1: ; -#IF (CPUFAM == CPU_Z80) + #IF (CPUFAM == CPU_Z80) ; LOOP TARGET IS 4000 T-STATES, SO CPU FREQ IN KHZ = LOOP COUNT * 4 CALL DLY32 CALL DLY16 @@ -3364,9 +5047,9 @@ HB_WAITSEC1: SBC HL,HL ; 15 TSTATES INC HL ; 6 TSTATES INC HL ; 6 TSTATES -#ENDIF + #ENDIF ; -#IF (CPUFAM == CPU_Z180) + #IF (CPUFAM == CPU_Z180) ; LOOP TARGET IS 4000 T-STATES, SO CPU FREQ IN KHZ = LOOP COUNT * 4 CALL DLY2 ADD IX,BC ; 10 + 4 = 14 TSTATES @@ -3374,7 +5057,7 @@ HB_WAITSEC1: NOP ; 5 TSTATES NOP ; 5 TSTATES NOP ; 5 TSTATES -#ENDIF + #ENDIF ; PUSH DE ; SAVE COUNTER CALL HB_RDSEC ; GET SECONDS @@ -3397,12 +5080,75 @@ HB_RDSEC: LD A,E ; VALUE TO A RET ; -#ELSE + #ELSE ; RET ; NO RTC, ABORT ; #ENDIF ; +; SYSTEM CHECK: DUMP MACHINE STATE AND CONTINUE? +; +SYSCHK: + ; CHECK DIAG LEVEL TO SEE IF WE SHOULD DISPLAY + PUSH AF ; PRESERVE INCOMING AF VALUE + LD A,(CB_DIAGLVL) ; GET DIAGNOSTIC LEVEL + CP DL_ERROR ; >= ERROR LEVEL + JR C,SYSCHK1 ; IF NOT, GO HOME + POP AF ; RESTORE INCOMING AF VALUE +; + ; DISPLAY SYSCHK MESSAGE + PUSH DE ; PRESERVE DE VALUE + LD DE,STR_SYSCHK ; POINT TO PREFIX STRING + CALL WRITESTR ; PRINT IT + POP DE ; RESTORE DE VALUE + CALL XREGDMP ; DUMP REGISTERS + JR CONTINUE ; CHECK W/ USER +; +SYSCHK1: + ; RETURN IF MESSAGING BYPASSED BY DIAG LEVEL + POP AF + RET +; +; PANIC: DUMP MACHINE STATE AND HALT +; +PANIC: + PUSH DE + LD DE,STR_PANIC + CALL WRITESTR + POP DE + CALL XREGDMP ; DUMP REGISTERS + JR SYSHALT ; FULL STOP +; +; +; +CONTINUE: + PUSH AF +CONTINUE1: + PUSH DE + LD DE,STR_CONTINUE + CALL WRITESTR + POP DE + CALL CIN + RES 5,A ; FORCE UPPERCASE (IMPERFECTLY) + CALL COUT ; ECHO + CP 'Y' + JR Z,CONTINUE3 + CP 'N' + JR Z,SYSHALT + JR CONTINUE1 +CONTINUE3: + CALL NEWLINE + POP AF + RET +; +; +; +SYSHALT: + LD DE,STR_HALT + CALL WRITESTR + DI + HALT +; ; PRINT VALUE OF HL AS THOUSANDTHS, IE. 0.000 ; PRTD3M: @@ -3455,10 +5201,14 @@ PRTSUM: LD C,BF_SYSGET_DIOCNT ; DISK DRIVES LD HL,PS_DISK CALL PRT_ALLD - +; LD C,BF_SYSGET_VDACNT ; VIDEO DEVICES LD HL,PS_VIDEO CALL PRT_ALLD +; + LD C,BF_SYSGET_SNDCNT ; SOUND DEVICES + LD HL,PS_SOUND + CALL PRT_ALLD RET ; PRT_ALLD: @@ -3551,6 +5301,8 @@ PS_PRTDC: JR Z,PS_PRTDC1 ; PRINT CAPACITY IN KB CP 5 ; RAM DISK? JR Z,PS_PRTDC1 ; PRINT CAPACITY IN KB + CP 7 ; FLASH DISK? + JR Z,PS_PRTDC1 ; PRINT CAPACITY IN KB ; ; PRINT HARD DISK STORAGE SIZE IN MB LD B,BF_DIOCAP ; HBIOS FUNC: GET CAPACTIY @@ -3801,6 +5553,73 @@ PS_PRTVC: CALL PRTDECB RET ; +; PRINT SOUND CONFIG +; +PS_SOUND: + PUSH BC + + ; UNIT COLUMN + PRTS("Sound $") + LD A,C ; MOVE UNIT NUM TO A + CALL PRTDECB ; PRINT IT + CP 10 ; CHECK FOR MULTIPLE DIGITS + CALL C,PC_SPACE ; EXTRA SPACE IF NEEDED + PRTS(" $") ; PAD TO NEXT COLUMN + + ; DEVICE COLUMN + + PUSH BC ; + LD E,C + XOR A + LD DE,PS_SDSND ; POINT TO DEVICE TYPE NAME TABLE + CALL PRTIDXDEA ; PRINT DEVICE NMEMONIC PADDED TO FIELD WIDTH + LD A,C ; MOVE UNIT NUM TO A + CALL PRTDECB ; PRINT IT + CALL PC_COLON + CP 10 ; CHECK FOR MULTIPLE DIGITS + CALL C,PC_SPACE ; EXTRA SPACE IF NEEDED + LD A,(PRTIDXCNT) + SUB 9+1 + CPL + CALL PS_PAD + POP BC + + ; DEVICE TYPE +; + LD B,BF_SNDQUERY ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C + LD E,BF_SNDQ_DEV + RST 08 + LD A,B + ;DEC A + RLCA + RLCA + RLCA + RLCA + AND $0F + LD DE,PS_SDSN76489 + CALL PRTIDXDEA + LD A,(PRTIDXCNT) + SUB 18+1 + CPL + CALL PS_PAD ; PAD N SPACES (SPECIFIED IN A) + + ; DEVICE CHARACTERISTICS +; + LD B,BF_SNDQUERY ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C + LD E,BF_SNDQ_CHCNT + RST 08 + LD A,B + CALL PRTDECB + LD A,'+' + CALL COUT + LD A,C + CALL PRTDECB + PRTS(" CHANNELS$") + CALL NEWLINE +; + POP BC + RET +; ; PRINT DEVICE NMEMONIC, DEVTYP/NUM SPECIFIED IN DE ; PS_PRTDEV: @@ -3855,10 +5674,11 @@ PS_PAD1: DJNZ PS_PAD1 RET ; -HB_CPU_STR: .TEXT " Z80$" ; HB_STRZ80 - .TEXT " Z80180$" ; HB_STRZ180 - .TEXT " Z8S180-K$" ; HB_STRZS180K - .TEXT " Z8S180-N$" ; HB_STRZS180N +HB_CPU_STR: .TEXT " Z80$" + .TEXT " Z80180$" + .TEXT " Z8S180-K$" + .TEXT " Z8S180-N$" + .TEXT " Z80280$" ; PS_STRNUL .TEXT "--$" ; DISPLAY STRING FOR NUL VALUE ; @@ -3883,7 +5703,7 @@ PS_DDHDSK .TEXT "HDSK$" ; PS_DTSTRREF: .DW PS_DTFLOP, PS_DTHARD, PS_DTCF, PS_DTSD - .DW PS_DTUSB, PS_DTROM, PS_DTRAM, PS_DTRF + .DW PS_DTUSB, PS_DTROM, PS_DTRAM, PS_DTRF, PS_DTFSH ; PS_DTFLOP .TEXT "Floppy Disk$" PS_DTHARD .TEXT "Hard Disk$" @@ -3893,6 +5713,7 @@ PS_DTUSB .TEXT "USB Drive$" PS_DTROM .TEXT "ROM Disk$" PS_DTRAM .TEXT "RAM Disk$" PS_DTRF .TEXT "RAM Floppy$" +PS_DTFSH .TEXT "Flash Drive$" PS_DTOTHER .TEXT "???$" ; ; FLOPPY ATTRIBUTE STRINGS @@ -3905,7 +5726,7 @@ PS_FLP_FSTR: .TEXT "8\",$" ; PS_FLP8 PS_FLP_SSTR: .TEXT "SS/$" ; PS_FLPSS .TEXT "DS/$" ; PS_FLPDS ; -PS_FLP_DSTR: .TEXT "SD$" ; PS_FLPSD +PS_FLP_DSTR: .TEXT "SD$" ; PS_FLPSD .TEXT "DD$" ; PS_FLPDD .TEXT "HD$" ; PS_FLPHD .TEXT "ED$" ; PS_FLPED @@ -3913,8 +5734,8 @@ PS_FLP_DSTR: .TEXT "SD$" ; PS_FLPSD ; CHARACTER DEVICE STRINGS ; PS_SDSTRREF: - .DW PS_SDUART, PS_SDASCI, PS_SDTERM - .DW PS_SDPRPCON, PS_SDPPPCON, PS_SDSIO, PS_SDACIA, PS_SDPIO,PS_SDUF + .DW PS_SDUART, PS_SDASCI, PS_SDTERM, PS_SDPRPCON, PS_SDPPPCON + .DW PS_SDSIO, PS_SDACIA, PS_SDPIO, PS_SDUF, PS_SDDUART, PS_SDZ2U ; PS_SDUART .TEXT "UART$" PS_SDASCI .TEXT "ASCI$" @@ -3925,6 +5746,8 @@ PS_SDSIO .TEXT "SIO$" PS_SDACIA .TEXT "ACIA$" PS_SDPIO .TEXT "PORT$" PS_SDUF .TEXT "UF$" +PS_SDDUART .TEXT "DUART$" +PS_SDZ2U .TEXT "Z2U$" ; ; CHARACTER SUB TYPE STRINGS ; @@ -3956,6 +5779,16 @@ PS_VDVGA .TEXT "VGA$" ; PS_VTCRT .TEXT "CRT$" ; +; SOUND DEVICE STRINGS +; +PS_SDSND .TEXT "SND$" +; +; SOUND TYPE STRINGS +; +PS_SDSN76489 .TEXT "SN76489$" +PS_SDAY38910 .TEXT "AY-3-8910$" +PS_SDBITMODE .TEXT "I/O PORT$" +; ; 0 1 2 3 4 5 6 7 ; 01234567890123456789012345678901234567890123456789012345678901234567890123456789 PS_STRHDR .TEXT "Unit Device Type Capacity/Mode\r\n" @@ -4125,7 +5958,7 @@ IDLECOUNT .DB 0 HEAPCURB .DW 0 ; MARK HEAP ADDRESS AFTER INITIALIZATION ; HB_TICKS .FILL 4,0 ; 32 BIT TICK COUNTER -HB_SECTCK .DB TICKSPERSEC ; TICK COUNTER FOR FRACTIONAL SECONDS +HB_SECTCK .DB TICKFREQ ; TICK COUNTER FOR FRACTIONAL SECONDS HB_SECS .FILL 4,0 ; 32 BIT SECONDS COUNTER ; HB_CPUTYPE .DB 0 ; 0=Z80, 1=80180, 2=SL1960, 3=ASCI BRG @@ -4144,6 +5977,10 @@ STR_SWITCH .DB "*** Activating CRT Console ***$" STR_BADINT .DB "\r\n*** BAD INT ***\r\n$" STR_LOWBAT .DB "\r\n\r\n+++ LOW BATTERY +++$" ; +STR_PANIC .TEXT "\r\n>>> PANIC: $" +STR_SYSCHK .TEXT "\r\n>>> SYSCHK: $" +STR_CONTINUE .TEXT "\r\nContinue (Y/N)? $" +; #IF (DSKYENABLE) ; 'H','B','I','O',' ',' ',' ',' ' MSG_HBVER .DB $BE,$FF,$8A,$FB,$80,$80,$80,$80 ; "HBIO " #ENDIF diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index 6c166307..bdee24ed 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -32,6 +32,9 @@ BF_RTCGETBYT .EQU BF_RTC + 2 ; GET NVRAM BYTE BY INDEX BF_RTCSETBYT .EQU BF_RTC + 3 ; SET NVRAM BYTE BY INDEX BF_RTCGETBLK .EQU BF_RTC + 4 ; GET NVRAM DATA BLOCK BF_RTCSETBLK .EQU BF_RTC + 5 ; SET NVRAM DATA BLOCK +BF_RTCGETALM .EQU BF_RTC + 6 ; GET ALARM +BF_RTCSETALM .EQU BF_RTC + 7 ; SET ALARM +BF_RTCDEVICE .EQU BF_RTC + 8 ; RTC DEVICE INFO REPORT ; BF_EMU .EQU $30 ; DEPRECATED ; @@ -52,6 +55,23 @@ BF_VDAKST .EQU BF_VDA + 12 ; GET KEYBOARD STATUS BF_VDAKFL .EQU BF_VDA + 13 ; FLUSH KEYBOARD BUFFER BF_VDAKRD .EQU BF_VDA + 14 ; READ KEYBOARD ; +BF_SND .EQU $50 +BF_SNDRESET .EQU BF_SND + 0 ; RESET SOUND SYSTEM +BF_SNDVOL .EQU BF_SND + 1 ; REQUEST SOUND VOL - L CONTAINS VOLUME (255 MAX, 0 SILENT) - SCALED AS REQUIRED BY DRIVER (EG: MAPS TO JUST 4 BIT RESOLUTION FOR SN76489) +BF_SNDPRD .EQU BF_SND + 2 ; REQUEST SOUND PERIOD - HL CONTAINS DRIVER SPECIFIC VALUE +BF_SNDNOTE .EQU BF_SND + 3 ; REQUEST NOTE - L CONTAINS NOTE - EACH VALUE IS QUARTER NOTE +BF_SNDPLAY .EQU BF_SND + 4 ; INITIATE THE REQUESTED SOUND COMMAND +BF_SNDQUERY .EQU BF_SND + 5 ; E IS SUBFUNCTION +BF_SNDDURATION .EQU BF_SND + 6 ; REQUEST DURATION HL MILLISECONDS +BF_SNDDEVICE .EQU BF_SND + 7 ; SOUND DEVICE INFO REQUEST +; +; BF_SNDQUERY SUBCOMMANDS +BF_SNDQ_STATUS .EQU 0 +BF_SNDQ_CHCNT .EQU BF_SNDQ_STATUS + 1 ; RETURN COUNT OF CHANNELS +BF_SNDQ_VOLUME .EQU BF_SNDQ_STATUS + 2 ; 8 BIT NUMBER +BF_SNDQ_PERIOD .EQU BF_SNDQ_STATUS + 3 ; 16 BIT NUMBER +BF_SNDQ_DEV .EQU BF_SNDQ_STATUS + 4 ; RETURN DEVICE TYPE CODE AND IO PORTS - TYPE IN B, PORTS IN DE, HL +; BF_SYS .EQU $F0 BF_SYSRESET .EQU BF_SYS + 0 ; SOFT RESET HBIOS BF_SYSVER .EQU BF_SYS + 1 ; GET HBIOS VERSION @@ -67,9 +87,19 @@ BF_SYSPEEK .EQU BF_SYS + 10 ; GET A BYTE VALUE FROM ALT BANK BF_SYSPOKE .EQU BF_SYS + 11 ; SET A BYTE VALUE IN ALT BANK BF_SYSINT .EQU BF_SYS + 12 ; MANAGE INTERRUPT VECTORS ; +BF_SYSRES_INT .EQU $00 ; RESET HBIOS INTERNAL +BF_SYSRES_WARM .EQU $01 ; WARM START (RESTART BOOT LOADER) +BF_SYSRES_COLD .EQU $02 ; COLD START +; BF_SYSGET_CIOCNT .EQU $00 ; GET CHAR UNIT COUNT +BF_SYSGET_CIOFN .EQU $01 ; GET CIO UNIT FN/DATA ADR BF_SYSGET_DIOCNT .EQU $10 ; GET DISK UNIT COUNT +BF_SYSGET_DIOFN .EQU $11 ; GET DIO UNIT FN/DATA ADR +BF_SYSGET_RTCCNT .EQU $20 ; GET RTC UNIT COUNT BF_SYSGET_VDACNT .EQU $40 ; GET VDA UNIT COUNT +BF_SYSGET_VDAFN .EQU $41 ; GET VDA UNIT FN/DATA ADR +BF_SYSGET_SNDCNT .EQU $50 ; GET VDA UNIT COUNT +BF_SYSGET_SNDFN .EQU $51 ; GET SND UNIT FN/DATA ADR BF_SYSGET_TIMER .EQU $D0 ; GET CURRENT TIMER VALUE BF_SYSGET_SECS .EQU $D1 ; GET CURRENT SECONDS VALUE BF_SYSGET_BOOTINFO .EQU $E0 ; GET BOOT INFORMATION @@ -87,6 +117,38 @@ BF_SYSINT_SET .EQU $20 ; SET INT VECTOR ADDRESS ; CIO_CONSOLE .EQU $80 ; CIO UNIT NUM FOR CUR CON ; +; HBIOS GLOBAL ERROR RETURN VALUES +; +ERR_NONE .EQU 0 ; SUCCESS +; +ERR_UNDEF .EQU -1 ; UNDEFINED ERROR +ERR_NOTIMPL .EQU -2 ; FUNCTION NOT IMPLEMENTED +ERR_NOFUNC .EQU -3 ; INVALID FUNCTION +ERR_NOUNIT .EQU -4 ; INVALID UNIT NUMBER +ERR_NOMEM .EQU -5 ; OUT OF MEMORY +ERR_RANGE .EQU -6 ; PARAMETER OUT OF RANGE +ERR_NOMEDIA .EQU -7 ; MEDIA NOT PRESENT +ERR_NOHW .EQU -8 ; HARDWARE NOT PRESENT +ERR_IO .EQU -9 ; I/O ERROR +ERR_READONLY .EQU -10 ; WRITE REQUEST TO READ-ONLY MEDIA +ERR_TIMEOUT .EQU -11 ; DEVICE TIMEOUT +ERR_BADCFG .EQU -12 ; INVALID CONFIGURATION +ERR_INTERNAL .EQU -13 ; INTERNAL ERROR +; +; MEDIA ID VALUES +; +MID_NONE .EQU 0 +MID_MDROM .EQU 1 +MID_MDRAM .EQU 2 +MID_RF .EQU 3 +MID_HD .EQU 4 +MID_FD720 .EQU 5 +MID_FD144 .EQU 6 +MID_FD360 .EQU 7 +MID_FD120 .EQU 8 +MID_FD111 .EQU 9 +MID_HDNEW .EQU 10 +; ; CHAR DEVICE IDS ; CIODEV_UART .EQU $00 @@ -98,6 +160,8 @@ CIODEV_SIO .EQU $50 CIODEV_ACIA .EQU $60 CIODEV_PIO .EQU $70 CIODEV_UF .EQU $80 +CIODEV_DUART .EQU $90 +CIODEV_Z2U .EQU $A0 ; ; SUB TYPES OF CHAR DEVICES ; @@ -119,6 +183,13 @@ DIODEV_PRPSD .EQU $70 DIODEV_PPPSD .EQU $80 DIODEV_HDSK .EQU $90 ; +; RTC DEVICE IDS +; +RTCDEV_DS .EQU $00 ; DS1322 +RTCDEV_BQ .EQU $10 ; BQ4845P +RTCDEV_SIMH .EQU $30 ; SIMH +RTCDEV_INT .EQU $40 ; PERIODIC INT TIMER +; ; VIDEO DEVICE IDS ; VDADEV_VDU .EQU $00 ; ECB VDU - MOTOROLA 6545 @@ -126,12 +197,12 @@ VDADEV_CVDU .EQU $10 ; ECB COLOR VDU - MOS 8563 VDADEV_NEC .EQU $20 ; ECB UPD7220 - NEC UPD7220 VDADEV_TMS .EQU $30 ; N8 ONBOARD VDA SUBSYSTEM - TMS 9918 VDADEV_VGA .EQU $40 ; ECB VGA3 - HITACHI HD6445 -;; -;; EMULATION TYPES - moved to std.asm -;; -;EMUTYP_NONE .EQU 0 ; NONE -;EMUTYP_TTY .EQU 1 ; TTY -;EMUTYP_ANSI .EQU 2 ; ANSI +; +; SOUND DEVICE IDS +; +SNDDEV_SN76489 .EQU $00 +SNDDEV_AY38910 .EQU $10 +SNDDEV_BITMODE .EQU $20 ; ; HBIOS CONTROL BLOCK OFFSETS ; WARNING: THESE OFFSETS WILL CHANGE SIGNIFICANTLY BETWEEN RELEASES @@ -152,8 +223,7 @@ HCB_BOOTBID .EQU $0F ; BANK ID OF ROM PAGE BOOTED (BYTE) HCB_SERDEV .EQU $10 ; PRIMARY SERIAL DEVICE/UNIT (BYTE) HCB_CRTDEV .EQU $11 ; CRT DISPLAY DEVICE/UNIT (BYTE) HCB_CONDEV .EQU $12 ; ACTIVE CONSOLE DEVICE/UNIT (BYTE) -;HCB_CUREMU .EQU $13 ; CURRENT VDA TERMINAL EMULATION (DEPRECATED) -;HCB_CURVDA .EQU $14 ; CURRENT VDA TARGET FOR EMULATION (DEPRECATED) +HCB_DIAGLVL .EQU $13 ; HBIOS DIAGNOSTIC LEVEL (BYTE) ; HCB_HEAP .EQU $20 ; DWORD ADDRESS OF START OF HEAP HCB_HEAPTOP .EQU $22 ; DWORD ADDRESS OF TOP OF HEAP diff --git a/Source/HBIOS/hdsk.asm b/Source/HBIOS/hdsk.asm index 3c8825bb..f3cabdad 100644 --- a/Source/HBIOS/hdsk.asm +++ b/Source/HBIOS/hdsk.asm @@ -27,10 +27,12 @@ HDSK_CFGTBL: .DB 0 ; DRIVER DEVICE NUMBER .DB 0 ; DEVICE STATUS .DW 0,0 ; CURRENT LBA +#IF (HDSK_DEVCNT >= 2) ; DEVICE 1 .DB 1 ; DEVICE NUMBER .DB 0 ; DEVICE STATUS .DW 0,0 ; CURRENT LBA +#ENDIF ; #IF ($ - HDSK_CFGTBL) != (HDSK_DEVCNT * HDSK_CFGSIZ) .ECHO "*** INVALID HDSK CONFIG TABLE ***\n" @@ -119,7 +121,10 @@ HDSK_FNTBL: HDSK_VERIFY: HDSK_FORMAT: HDSK_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL SYSCHK ; INVALID SUB-FUNCTION + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -135,15 +140,11 @@ HDSK_RESET: ; ; GET DISK CAPACITY ; RETURN DE:HL=BLOCK COUNT, BC=BLOCK SIZE -; SLICE C/H/S = 65/16/16 OR 16,640 TOTAL SECTORS -; ASSUME 8 SLICES, SO 16640 X 8 = 133,120 TOTAL SECTORS -; -; 2048 TRKS X 16 HDS X 16 SPT = 524288 OR 80000H +; ASSUME 1GB MEDIA SIZE, SO 1GB / 512B +; IS $200000 SECTORS ; HDSK_CAP: - ;LD DE,133120 >> 16 ; BLOCK COUNT MSW - ;LD HL,133120 & $FFFF ; BLOCK COUNT LSW - LD DE,8 ; BLOCK COUNT MSW + LD DE,$20 ; BLOCK COUNT MSW LD HL,0 ; BLOCK COUNT LSW LD BC,512 ; 512 BYTE SECTOR XOR A ; SIGNAL SUCCESS @@ -168,6 +169,8 @@ HDSK_DEVICE: LD D,DIODEV_HDSK ; D := DEVICE TYPE LD E,(IY+HDSK_DEV) ; E := PHYSICAL DEVICE NUMBER LD C,%00000000 ; C := ATTRIBUTES, NON-REMOVABLE HARD DISK + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,HDSK_IO ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -293,7 +296,10 @@ HDSK_RW6: LD E,C ; SECTOR READ COUNT TO E LD HL,(HDSK_DMA) ; CURRENT DMA TO HL OR A ; SET FLAGS BASED ON RETURN CODE - RET ; AND RETURN, A HAS RETURN CODE + RET Z ; RETURN IF SUCCESS + LD A,ERR_IO ; SIGNAL IO ERROR + OR A ; SET FLAGS + RET ; AND DONE ; ; ; diff --git a/Source/HBIOS/ide.asm b/Source/HBIOS/ide.asm index c018384a..8613e8a3 100644 --- a/Source/HBIOS/ide.asm +++ b/Source/HBIOS/ide.asm @@ -461,7 +461,10 @@ IDE_FNTBL: IDE_VERIFY: IDE_FORMAT: IDE_DEFMED: - CALL PANIC ; NOT IMPLEMENTED + CALL SYSCHK ; NOT IMPLEMENTED + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -520,7 +523,10 @@ IDE_IO3: LD E,C ; SECTOR READ COUNT TO E LD HL,(IDE_DSKBUF) ; CURRENT DMA TO HL OR A ; SET FLAGS BASED ON RETURN CODE - RET ; AND RETURN, A HAS RETURN CODE + RET Z ; RETURN IF SUCCESS + LD A,ERR_IO ; SIGNAL IO ERROR + OR A ; SET FLAGS + RET ; AND DONE ; ; ; @@ -540,6 +546,8 @@ IDE_DEVICE: JR Z,IDE_DEVICE1 ; IF Z, WE ARE DONE LD C,%01001000 ; OTHERWISE REMOVABLE COMPACT FLASH IDE_DEVICE1: + LD H,(IY+IDE_MODE) ; H := MODE + LD L,(IY+IDE_IOBASE) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -574,6 +582,8 @@ IDE_MEDIA2: LD E,MID_HD ; ASSUME WE ARE OK RET Z ; RETURN IF GOOD INIT LD E,MID_NONE ; SIGNAL NO MEDIA + LD A,ERR_NOMEDIA ; NO MEDIA ERROR + OR A ; SET FLAGS RET ; AND RETURN ; ; @@ -922,36 +932,15 @@ IDE_RESET: PRTS(" RESET$") #ENDIF ; -;#IF (IDEMODE == IDEMODE_MK4) -; - LD A,(IY+IDE_MODE) ; GET MODE - CP IDEMODE_MK4 ; MK4? - JR NZ,IDE_RESET1 ; IF NOT, BYPASS -; - ; USE HARDWARE RESET LINE -#IF (IDETRACE >= 3) - PRTS(" HARD$") -#ENDIF - LD A,$80 ; HIGH BIT OF XAR IS IDE RESET - ;OUT (IDE_IO_XAR),A - CALL IDE_OUT - .DB IDE_REG_XAR - LD DE,2 ; DELAY 32US (SPEC IS >= 25US) - CALL VDELAY - XOR A ; CLEAR RESET BIT - ;OUT (IDE_IO_XAR),A - CALL IDE_OUT - .DB IDE_REG_XAR -; -IDE_RESET1: -; -;#ENDIF -; ;#IF (IDEMODE == IDEMODE_RC) ; - LD A,(IY+IDE_MODE) ; GET MODE - CP IDEMODE_RC ; RC2014? - JR NZ,IDE_RESET2 ; IF NOT, BYPASS + ; OLDER CF CARDS DO NOT SEEM TO SET THE + ; REGISTERS ON RESET, SO HERE WE FAKE THINGS BY + ; SETTING THEM AS A RESET WOULD. SO WE ALWAYS + ; DO THE FAKE. + ;LD A,(IY+IDE_MODE) ; GET MODE + ;CP IDEMODE_RC ; RC2014? + ;JR NZ,IDE_RESET2 ; IF NOT, BYPASS ; ; RC2014 CANNOT ADDRESS THE DEVICE CONTROL PORT AND ; HAS NO WAY TO PERFORM A HARD RESET FROM SOFTWARE, @@ -979,6 +968,33 @@ IDE_RESET2: ; ;#ENDIF ; +;#IF (IDEMODE == IDEMODE_MK4) +; + LD A,(IY+IDE_MODE) ; GET MODE + CP IDEMODE_MK4 ; MK4? + JR NZ,IDE_RESET1 ; IF NOT, BYPASS +; + ; USE HARDWARE RESET LINE +#IF (IDETRACE >= 3) + PRTS(" HARD$") +#ENDIF + LD A,$80 ; HIGH BIT OF XAR IS IDE RESET + ;OUT (IDE_IO_XAR),A + CALL IDE_OUT + .DB IDE_REG_XAR + LD DE,20 ; DELAY 32US (SPEC IS >= 25US) + CALL VDELAY + XOR A ; CLEAR RESET BIT + ;OUT (IDE_IO_XAR),A + CALL IDE_OUT + .DB IDE_REG_XAR + LD DE,20 + CALL VDELAY +; +IDE_RESET1: +; +;#ENDIF +; ;#IF ((IDEMODE != IDEMODE_MK4) & (IDEMODE != IDEMODE_RC)) ; LD A,(IY+IDE_MODE) ; GET MODE diff --git a/Source/HBIOS/intrtc.asm b/Source/HBIOS/intrtc.asm index 0414a286..6602b3a3 100644 --- a/Source/HBIOS/intrtc.asm +++ b/Source/HBIOS/intrtc.asm @@ -50,7 +50,16 @@ INTRTC_DISPATCH: JP Z,INTRTC_GETBLK ; GET NVRAM DATA BLOCK VALUES DEC A JP Z,INTRTC_SETBLK ; SET NVRAM DATA BLOCK VALUES - CALL PANIC + DEC A + JP Z,INTRTC_GETALM ; GET ALARM + DEC A + JP Z,INTRTC_SETALM ; SET ALARM + DEC A + JP Z,INTRTC_DEVICE ; REPORT RTC DEVICE INFO + CALL SYSCHK + LD A,ERR_NOFUNC + OR A + RET ; ; NVRAM FUNCTIONS ARE NOT AVAILABLE IN SIMULATOR ; @@ -58,7 +67,12 @@ INTRTC_GETBYT: INTRTC_SETBYT: INTRTC_GETBLK: INTRTC_SETBLK: - CALL PANIC +INTRTC_GETALM: +INTRTC_SETALM: + CALL SYSCHK + LD A,ERR_NOTIMPL + OR A + RET ; ; RTC GET TIME ; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR @@ -119,6 +133,16 @@ INTRTC_SETTIM: XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; +; REPORT RTC DEVICE INFO +; +INTRTC_DEVICE: + LD D,RTCDEV_INT ; D := DEVICE TYPE + LD E,0 ; E := PHYSICAL DEVICE NUMBER + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,0 ; L := 0, NO I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; ; HANDLER FOR TIMER SECONDS INTERRUPT ; INTRTC_INT: @@ -181,7 +205,7 @@ INTRTC_INT2: JR NZ,INTRTC_INTX ; NOPE, DONE LD (HL),0 ; BACK TO YEAR ZERO INTRTC_INTX: - JP PANIC + JP SYSCHK INTRTC_VEC .EQU $-2 ; ; CONVERT FROM BINARY BUF (HL) TO BCD BUF (DE) diff --git a/Source/HBIOS/md.asm b/Source/HBIOS/md.asm index 2b9c9c0a..eb4c2446 100644 --- a/Source/HBIOS/md.asm +++ b/Source/HBIOS/md.asm @@ -5,12 +5,29 @@ ; ; MD DEVICE CONFIGURATION ; +; +; DISK DEVICE TYPE ID MEDIA ID ATTRIBUTE +;-------------------------------------------------------------------------------------------------- +; 0x00 MEMORY DISK 0x02 RAM DRIVE %00101000 HD STYLE, NON-REMOVABLE, TYPE-RAM +; 0x00 MEMORY DISK 0x01 ROM DRIVE %00100000 HD STYLE, NON-REMOVABLE, TYPE-ROM +; 0x00 MEMORY DISK 0x01 ROM DRIVE %00111000 HD STYLE, NON-REMOVABLE, TYPE-FLASH +; MD_DEVCNT .EQU 2 ; NUMBER OF MD DEVICES SUPPORTED -MD_CFGSIZ .EQU 6 ; SIZE OF CFG TBL ENTRIES +MD_CFGSIZ .EQU 8 ; SIZE OF CFG TBL ENTRIES ; MD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) MD_STAT .EQU 1 ; OFFSET OF STATUS (BYTE) MD_LBA .EQU 2 ; OFFSET OF LBA (DWORD) +MD_MID .EQU 6 ; OFFSET OF MEDIA ID (BYTE) +MD_ATTRIB .EQU 7 ; OFFSET OF ATTRIBUTE (BYTE) +; +MD_AROM .EQU %00100000 ; ROM ATTRIBUTE +MD_ARAM .EQU %00101000 ; RAM ATTRIBUTE +MD_AFSH .EQU %00111000 ; FLASH ATTRIBUTE +; +MD_FDBG .EQU 0 ; FLASH DEBUG CODE +MD_FVBS .EQU 1 ; FLASH VERBOSE OUTPUT +MD_FVAR .EQU 1 ; FLASH VERIFY AFTER WRITE ; ; DEVICE CONFIG TABLE (RAM DEVICE FIRST TO MAKE IT ALWAYS FIRST DRIVE) ; @@ -19,10 +36,14 @@ MD_CFGTBL: .DB 1 ; DRIVER DEVICE NUMBER .DB 0 ; DEVICE STATUS .DW 0,0 ; CURRENT LBA + .DB MID_MDRAM ; DEVICE MEDIA ID + .DB MD_ARAM ; DEVICE ATTRIBUTE ; DEVICE 0 (ROM) .DB 0 ; DEVICE NUMBER .DB 0 ; DEVICE STATUS .DW 0,0 ; CURRENT LBA + .DB MID_MDROM ; DEVICE MEDIA ID + .DB MD_AROM ; DEVICE ATTRIBUTE ; #IF ($ - MD_CFGTBL) != (MD_DEVCNT * MD_CFGSIZ) .ECHO "*** INVALID MD CONFIG TABLE ***\n" @@ -33,26 +54,38 @@ MD_CFGTBL: ; ; MD_INIT: +#IF (MDFFENABLE) + CALL MD_FINIT ; PROBE FLASH CAPABILITY +#ENDIF + CALL NEWLINE ; FORMATTING PRTS("MD: UNITS=2 $") PRTS("ROMDISK=$") LD HL,ROMSIZE - 128 CALL PRTDEC PRTS("KB RAMDISK=$") - LD HL,RAMSIZE - 128 + LD HL,RAMSIZE - 256 CALL PRTDEC PRTS("KB$") ; ; SETUP THE DIO TABLE ENTRIES ; +#IF (MDFFENABLE) + LD A,(MD_FFSEN) ; IF FLASH + OR A ; FILESYSTEM + JR NZ,MD_IN1 ; CAPABLE, + LD A,MD_AFSH ; UPDATE ROM DIO + LD (MD_CFGTBL + MD_CFGSIZ + MD_ATTRIB),A +MD_IN1: +#ENDIF LD BC,MD_FNTBL LD DE,MD_CFGTBL PUSH BC - CALL DIO_ADDENT + CALL DIO_ADDENT ; ADD FIRST ENTRY POP BC LD DE,MD_CFGTBL + MD_CFGSIZ - CALL DIO_ADDENT -; + CALL DIO_ADDENT ; ADD SECOND ENTRY + XOR A ; INIT SUCCEEDED RET ; RETURN ; @@ -80,13 +113,16 @@ MD_FNTBL: MD_VERIFY: MD_FORMAT: MD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL SYSCHK ; INVALID SUB-FUNCTION + LD A,ERR_NOTIMPL + OR A + RET ; ; ; MD_STATUS: - XOR A ; ALWAYS OK - RET +; XOR A ; ALWAYS OK +; RET ; ; ; @@ -95,25 +131,31 @@ MD_RESET: RET ; ; -; -MD_CAP: +; +MD_CAP: ; ASSUMES THAT UNIT 1 IS RAM, UNIT 0 IS ROM LD A,(IY+MD_DEV) ; GET DEVICE NUMBER OR A ; SET FLAGS JR Z,MD_CAP0 ; UNIT 0 DEC A ; TRY UNIT 1 JR Z,MD_CAP1 ; UNIT 1 - CALL PANIC ; PANIC ON INVALID UNIT + CALL SYSCHK ; INVALID UNIT + LD A,ERR_NOUNIT + OR A + RET MD_CAP0: LD A,(HCB + HCB_ROMBANKS) ; POINT TO ROM BANK COUNT + LD B,4 ; SET # RESERVED ROM BANKS JR MD_CAP2 MD_CAP1: LD A,(HCB + HCB_RAMBANKS) ; POINT TO RAM BANK COUNT + LD B,8 ; SET # RESERVED RAM BANKS MD_CAP2: - SUB 4 ; SUBTRACT OUT RESERVED BANKS + SUB B ; SUBTRACT OUT RESERVED BANKS LD H,A ; H := # BANKS LD E,64 ; # 512 BYTE BLOCKS / BANK CALL MULT8 ; HL := TOTAL # 512 BYTE BLOCKS LD DE,0 ; NEVER EXCEEDS 64K, ZERO HIGH WORD + LD BC,512 ; 512 BYTE SECTOR XOR A RET ; @@ -123,36 +165,33 @@ MD_GEOM: ; RAM/ROM DISKS ALLOW CHS STYLE ACCESS BY EMULATING ; A DISK DEVICE WITH 1 HEAD AND 16 SECTORS / TRACK. CALL MD_CAP ; HL := CAPACITY IN BLOCKS + PUSH BC ; SAVE SECTOR SIZE LD D,1 | $80 ; HEADS / CYL := 1 BY DEFINITION, SET LBA CAPABILITY BIT - LD E,16 ; SECTORS / TRACK := 16 BY DEFINTION + LD E,16 ; SECTORS / TRACK := 16 BY DEFINITION LD B,4 ; PREPARE TO DIVIDE BY 16 MD_GEOM1: SRL H ; SHIFT H RR L ; SHIFT L DJNZ MD_GEOM1 ; DO 4 BITS TO DIVIDE BY 16 + POP BC ; RECOVER SECTOR SIZE XOR A ; SIGNAL SUCCESS RET ; DONE ; ; ; MD_DEVICE: - LD D,DIODEV_MD ; D := DEVICE TYPE - LD A,(IY+MD_DEV) ; GET DEVICE NUMBER - LD E,A ; PUT IN E FOR RETURN - OR A ; SET FLAGS - LD C,%00100000 ; ASSUME ROM DISK ATTRIBUTES - JR Z,MD_DEVICE1 ; IF ZERO, IT IS ROM DISK, DONE - LD C,%00101000 ; USE RAM DISK ATTRIBUTES -MD_DEVICE1: + LD D,DIODEV_MD ; D := DEVICE TYPE - ALL ARE MEMORY DISKS + LD E,(IY+MD_DEV) ; GET DEVICE NUMBER + LD C,(IY+MD_ATTRIB) ; GET ATTRIBUTE + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,0 ; L := 0, NO BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; ; ; MD_MEDIA: - LD A,(IY+MD_DEV) ; GET DEVICE NUM - ADD A,MID_MDROM ; OFFSET BY MD ROM - LD E,A ; RESULTANT MEDIA ID TO E + LD E,(IY+MD_MID) ; GET MEDIA ID LD D,0 ; D:0=0 MEANS NO MEDIA CHANGE XOR A ; SIGNAL SUCCESS RET @@ -169,28 +208,46 @@ MD_SEEK: LD (IY+MD_LBA+3),D ; ... XOR A ; SIGNAL SUCCESS RET ; AND RETURN - ; ; ; MD_READ: CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR - LD BC,MD_RDSEC ; GET ADR OF SECTOR READ FUNC +; +; HL POINTS TO HB_WRKBUF +; +#IF (MDFFENABLE) + LD A,(IY+MD_ATTRIB) ; GET ADR OF SECTOR READ FUNC + LD BC,MD_RDSECF ; + CP MD_AFSH ; RAM / ROM = MD_RDSEC + JR Z,MD_RD1 ; FLASH = MD_RDSECF +#ENDIF + LD BC,MD_RDSEC +MD_RD1: LD (MD_RWFNADR),BC ; SAVE IT AS PENDING IO FUNC JR MD_RW ; CONTINUE TO GENERIC R/W ROUTINE - ; ; ; MD_WRITE: CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR - LD BC,MD_WRSEC ; GET ADR OF SECTOR WRITE FUNC +; +#IF (MDFFENABLE) + LD A,(IY+MD_ATTRIB) ; GET ADR OF SECTOR WRITE FUNC + LD BC,MD_WRSECF ; + CP MD_AFSH ; RAM / ROM = MD_WRSEC + JR Z,MD_WR1 ; FLASH = MD_WRSECF +#ENDIF + LD BC,MD_WRSEC +MD_WR1: + LD (MD_RWFNADR),BC ; SAVE IT AS PENDING IO FUNC - LD A,(IY+MD_DEV) ; GET DEVICE NUMBER - OR A ; SET FLAGS TO TEST FOR ROM (UNIT 0) - JR NZ,MD_RW ; NOT ROM, SO OK TO WRITE, CONTINUE + LD A,(IY+MD_ATTRIB) ; IF THE DEVICES ATTRIBUTE + CP MD_AROM ; IS NOT ROM THEN WE CAN + JR NZ,MD_RW ; WRITE TO IT LD E,0 ; UNIT IS READ ONLY, ZERO SECTORS WRITTEN - OR $FF ; SIGNAL ERROR + LD A,ERR_READONLY ; SIGNAL ERROR + OR A ; SET FLAGS RET ; AND DONE ; ; @@ -205,7 +262,13 @@ MD_RW: MD_RW1: PUSH BC ; SAVE COUNTERS LD HL,(MD_RWFNADR) ; GET PENDING IO FUNCTION ADDRESS +#IF (MDFFENABLE) + PUSH IX + CALL JPHL ; ... AND CALL IT + POP IX +#ELSE CALL JPHL ; ... AND CALL IT +#ENDIF JR NZ,MD_RW2 ; IF ERROR, SKIP INCREMENT ; INCREMENT LBA LD A,MD_LBA ; LBA OFFSET IN CFG ENTRY @@ -227,7 +290,191 @@ MD_RW3: OR A ; SET FLAGS BASED ON RETURN CODE RET ; AND RETURN, A HAS RETURN CODE ; +; READ FLASH +; +#IF (MDFFENABLE) +MD_RDSECF: ; CALLED FROM MD_RW +; + CALL MD_IOSETUPF ; SETUP SOURCE ADDRESS +; + PUSH HL ; IS THE SECTOR + LD HL,(MD_LBA4K) ; WE WANT TO + XOR A ; READ ALREADY + SBC HL,BC ; IN THE 4K + POP HL ; BLOCK WE HAVE + JR Z,MD_SECM ; IN THE BUFFER? +; + ; DESIRED SECTOR IS NOT IN BUFFER + LD (MD_LBA4K),BC ; WE WILL READ IN A NEW 4K SECTOR. + ; SAVE THE 4K LBA FOR FUTURE CHECKS +; + CALL MD_CALBAS ; SETUP BANK AND SECTOR +; + LD IX,MD_F4KBUF ; SET DESTINATION ADDRESS + LD HL,MD_FREAD_R ; PUT ROUTINE TO CALL + CALL MD_FNCALL ; EXECUTE: READ 4K SECTOR +; +MD_SECM: + LD A,(IY+MD_LBA+0) ; GET SECTOR WITHIN 4K BLOCK + AND %00000111 ; AND CALCULATE OFFSET OFFSET + ADD A,A + LD D,A ; FROM THE START + LD E,0 +; + LD HL,MD_F4KBUF ; POINT TO THE SECTOR WE + ADD HL,DE ; WANT TO COPY + LD DE,(MD_DSKBUF) + LD BC,512 ; COPY ONE 512B SECTOR FROM THE + LDIR ; 4K SECTOR TO THE DISK BUFFER +; + XOR A + RET +; +; SETUP DE:HL AS THE SECTOR ADDRESS TO READ OR WRITE +; +; ON EXIT +; BC = LBA 4K BLOCK WE ARE ACCESSING +; DE:HL = MEMORY ADDRESS TO ACCESS IN FLASH +; +MD_IOSETUPF: + LD L,(IY+MD_LBA+0) ; HL := LOW WORD OF LBA + LD H,(IY+MD_LBA+1) + INC H ; SKIP FIRST 128MB (256 SECTORS) +; + LD A,L ; SAVE LBA 4K + AND %11111000 ; BLOCK WE ARE + LD C,A ; GOING TO + LD B,H ; ACCESS +; + LD D,0 ; CONVERT LBA + LD E,H ; TO ADDRESS + LD H,L ; MULTIPLY BY 512 + LD L,D ; DE:HL = HLX512 + SLA H + RL E + RL D +; + RET +; +;====================================================================== +; CALCULATE BANK AND ADDRESS DATA FROM MEMORY ADDRESS +; +; ON ENTRY DE:HL CONTAINS 32 BIT MEMORY ADDRESS. +; ON EXIT B CONTAINS BANK SELECT BYTE +; C CONTAINS HIGH BYTE OF SECTOR ADDRESS ; +; DDDDDDDDEEEEEEEE HHHHHHHHLLLLLLLL +; 3322222222221111 1111110000000000 +; 1098765432109876 5432109876543210 +; XXXXXXXXXXXXSSSS SSSSXXXXXXXXXXXX < S = SECTOR +; XXXXXXXXXXXXBBBB BXXXXXXXXXXXXXXX < B = BANK +;====================================================================== +; +MD_CALBAS: +; +#IF (MD_FDBG==1) + CALL PC_SPACE ; DISPLAY SECTOR + CALL PRTHEX32 ; SECTOR ADDRESS + CALL PC_SPACE ; IN DE:HL +#ENDIF +; + PUSH HL + LD A,E ; BOTTOM PORTION OF SECTOR + AND $0F ; ADDRESS THAT GETS WRITTEN + RLC H ; WITH ERASE COMMAND BYTE + RLA ; A15 GETS DROPPED OFF AND + LD B,A ; ADDED TO BANK SELECT +; + LD A,H ; TOP SECTION OF SECTOR + RRA ; ADDRESS THAT GETS WRITTEN + AND $70 ; TO BANK SELECT PORT + LD C,A + + POP HL +; + LD (MD_FBAS),BC ; SAVE BANK AND SECTOR FOR USE IN FLASH ROUTINES +; +#IF (MD_FDBG==1) + CALL PRTHEXWORD ; DISPLAY BANK AND + CALL PC_SPACE ; SECTOR RESULT +#ENDIF + + RET +; +; WRITE FLASH +; +MD_WRSECF: ; CALLED FROM MD_RW + CALL MD_IOSETUPF ; SETUP DESTINATION ADDRESS +; + PUSH HL ; IS THE SECTOR + LD HL,(MD_LBA4K) ; WE WANT TO + XOR A ; WRITE ALREADY + SBC HL,BC ; IN THE 4K + POP HL ; BLOCK WE HAVE + JR Z,MD_SECM1 ; IN THE BUFFER +; + LD (MD_LBA4K),BC ; SAVE 4K LBA +; + CALL MD_CALBAS ; SETUP BANK AND SECTOR +; + LD IX,MD_F4KBUF ; SET DESTINATION ADDRESS + LD HL,MD_FREAD_R ; PUT ROUTINE TO CALL + CALL MD_FNCALL ; EXECUTE: READ 4K SECTOR +; +MD_SECM1: ; DESIRED SECTOR IS IN BUFFER + LD HL,MD_FERAS_R ; PUT ROUTINE TO CALL + CALL MD_FNCALL ; EXECUTE: ERASE 4K SECTOR + OR A + RET NZ ; RETURN IF ERROR + ; + ; COPY 512B SECTOR INTO 4K SECTOR + ; + LD A,(IY+MD_LBA+0) ; GET SECTOR WITHIN 4K BLOCK + AND %00000111 ; AND CALCULATE OFFSET OFFSET + ADD A,A + LD D,A ; FROM THE START + LD E,0 +; + LD HL,MD_F4KBUF ; POINT TO THE SECTOR WE + ADD HL,DE ; WANT TO COPY + EX DE,HL +; + LD HL,(MD_DSKBUF) + LD BC,512 ; COPY ONE 512B SECTOR FROM THE + LDIR ; THE DISK BUFFER TO 4K SECTOR +; + LD IX,MD_F4KBUF ; SET SOURCE ADDRESS + LD HL,MD_FWRIT_R ; PUT ROUTINE TO CALL + CALL MD_FNCALL ; EXECUTE: WRITE 4K SECTOR +; + XOR A ; PRESUME SUCCESS STATUS +; +#IF (MD_FVAR==1) + LD IX,MD_F4KBUF ; SET SOURCE ADDRESS + LD HL,MD_FVERI_R ; PUT ROUTINE TO CALL + CALL MD_FNCALL ; EXECUTE: VERIFY 4K SECTOR +; + OR A + RET Z ; RETURN IF SUCCESSFUL +; + LD IX,MD_F4KBUF ; SET SOURCE ADDRESS ; RETRY + LD HL,MD_FWRIT_R ; PUT ROUTINE TO CALL ; WRITE + CALL MD_FNCALL ; EXECUTE: WRITE 4K SECTOR ; ONCE +; + LD IX,MD_F4KBUF ; SET SOURCE ADDRESS ; VERIFY + LD HL,MD_FVERI_R ; PUT ROUTINE TO CALL ; AGAIN + CALL MD_FNCALL ; EXECUTE: VERIFY 4K SECTOR +; + OR A ; SET FINAL STATUS AFTER RETRY +#ENDIF +; + RET +; +MD_LBA4K .DW $FFFF ; LBA OF CURRENT SECTOR +MD_FBAS .DW $FFFF ; BANK AND SECTOR +#ENDIF +; +; READ RAM / ROM ; MD_RDSEC: CALL MD_IOSETUP ; SETUP FOR MEMORY COPY @@ -258,7 +505,7 @@ MD_RDSEC: XOR A RET ; -; +; WRITE RAM ; MD_WRSEC: CALL MD_IOSETUP ; SETUP FOR MEMORY COPY @@ -356,17 +603,18 @@ MD_IOSETUP2: ; ROM ; ; ; +#IF (MDTRACE >= 2) MD_PRT: PUSH AF PUSH BC PUSH DE PUSH HL - +; CALL NEWLINE - +; LD DE,MDSTR_PREFIX CALL WRITESTR - +; CALL PC_SPACE LD DE,MDSTR_SRC CALL WRITESTR @@ -375,7 +623,7 @@ MD_PRT: CALL PC_COLON LD BC,(MD_SRC) CALL PRTHEXWORD - +; CALL PC_SPACE LD DE,MDSTR_DST CALL WRITESTR @@ -384,33 +632,305 @@ MD_PRT: CALL PC_COLON LD BC,(MD_DST) CALL PRTHEXWORD - +; CALL PC_SPACE LD DE,MDSTR_LEN CALL WRITESTR LD BC,(MD_LEN) CALL PRTHEXWORD - +; POP HL POP DE POP BC POP AF +; + RET +; +MDSTR_PREFIX .TEXT "MD:$" +MDSTR_SRC .TEXT "SRC=$" +MDSTR_DST .TEXT "DEST=$" +MDSTR_LEN .TEXT "LEN=$" +#ENDIF +; +;================================================================================================== +; FLASH DRIVERS +;================================================================================================== +; +; UPPER RAM BANK IS ALWAYS AVAILABLE REGARDLESS OF MEMORY BANK SELECTION. +; HBX_BNKSEL AND HB_CURBNK ARE ALWAYS AVAILABLE IN UPPER MEMORY. +; +; THE STACK IS IN UPPER MEMORY DURING BIOS INITIALIZATION BUT IS IN LOWER +; MEMORY DURING HBIOS CALLS. +; +; TO ACCESS THE FLASH CHIP FEATURES, CODE IS COPIED TO THE UPPER RAM BANK (HBX_BUF) +; AND THE FLASH CHIP IS SWITCHED INTO THE LOWER BANK. +; +; EACH FLASH ROUTINE MUST FIT INTO TO THE HBX_BUF, INCLUDING IT'S LOCAL STACK WHICH +; IS REQUIRED FOR CALLING THE BANK SWITCH ROUTINES. +; +; INSPIRED BY WILL SOWERBUTTS FLASH4 UTILITY - https://github.com/willsowerbutts/flash4/ +; +; REFERENCE ww1.microchip.com/downloads/en/DeviceDoc/SST39SF040.txt +; +;================================================================================================== +; +#IF (MDFFENABLE) +MD_TGTDEV .EQU 0B7BFH ; TARGET CHIP FOR R/W FILESYSTEM 39SF040 +; +;====================================================================== +; BIOS FLASH INITIALIZATION +; +; IDENTIFY AND DISPLAY FLASH CHIPS IN SYSTEM. +; USES MEMORY SIZE DEFINED BY BUILD CONFIGURATION. +;====================================================================== +; +MD_FINIT: + LD A,+(ROMSIZE/512) ; DISLAY NUMBER +#IF (MD_FVBS==1) + CALL NEWLINE ; OF UNITS + PRTS("MD: FLASH=$") + CALL PRTDECB ; CONFIGURED FOR. +#ENDIF + LD B,A ; NUMBER OF DEVICES TO PROBE + LD C,$00 ; START ADDRESS IS 0000:0000 IN DE:HL +MD_PROBE: + LD D,$00 ; SET ADDRESS IN DE:HL + LD E,C ; + LD H,D ; WE INCREASE E BY $08 + LD L,D ; ON EACH CYCLE THROUGH +; + PUSH BC +#IF (MD_FVBS==1) + CALL PC_SPACE + LD A,+(ROMSIZE/512)+1 + SUB B ; PRINT + CALL PRTDECB ; DEVICE + LD A,'=' ; NUMBER + CALL COUT +#ENDIF + PUSH HL + CALL MD_CALBAS ; SETUP BANK AND SECTOR + LD HL,MD_FIDEN_R ; PUT ROUTINE TO CALL + CALL MD_FNCALL ; EXECUTE: IDENTIFY FLASH CHIP + + LD HL,MD_TGTDEV ; IF WE MATCH WITH + XOR A ; A NON 39SF040 + SBC HL,BC ; CHIP SET THE + JR Z,MD_PR2 ; R/W FLAG TO R/O + LD HL,MD_FFSEN ; A NON ZERO VALUE + SET 0,(HL) ; MEANS WE CAN'T + ; ENABLE FLASH WRITING; +MD_PR2: + POP HL +#IF (MD_FVBS==1) + CALL MD_LAND ; LOOKUP AND DISPLAY +#ENDIF + POP BC +; + LD A,C ; UPDATE ADDRESS + ADD A,$08 ; TO NEXT DEVICE + LD C,A +; + DJNZ MD_PROBE ; ALWAYS AT LEAST ONE DEVICE +#IF (MD_FVBS==1) + CALL PRTSTRD + .TEXT " FLASH FILE SYSTEM $" + LD DE,MD_FFMSGDIS + LD A,(MD_FFSEN) + OR A + JR NZ,MD_PR1 + LD DE,MD_FFMSGENA +MD_PR1: CALL WRITESTR +#ENDIF + + XOR A ; INIT SUCCEEDED RET ; +;====================================================================== +; LOOKUP AND DISPLAY CHIP ; +; ON ENTRY BC CONTAINS CHIP ID +; ON EXIT A CONTAINS STATUS 0=SUCCESS, NZ=NOT IDENTIFIED +;====================================================================== ; -MD_RWFNADR .DW 0 +MD_LAND: ; -MD_DSKBUF .DW 0 +#IF (MD_FDBG==1) + PRTS(" ID:$") + CALL PRTHEXWORD ; DISPLAY FLASH ID + CALL PC_SPACE +#ENDIF ; + LD HL,MD_TABLE ; SEARCH THROUGH THE FLASH + LD DE,MD_T_CNT ; TABLE TO FIND A MATCH +MD_NXT1:LD A,(HL) + CP B + JR NZ,MD_NXT0 ; FIRST BYTE DOES NOT MATCH +; + INC HL + LD A,(HL) + CP C + DEC HL + JR NZ,MD_NXT0 ; SECOND BYTE DOES NOT MATCH +; + INC HL + INC HL + JR FF_NXT2 ; MATCH SO EXIT +; +MD_NXT0:PUSH BC ; WE DIDN'T MATCH SO POINT + LD BC,MD_T_SZ ; TO THE NEXT TABLE ENTRY + ADD HL,BC + POP BC +; + LD A,D ; CHECK IF WE REACHED THE + OR E ; END OF THE TABLE + DEC DE + JR NZ,MD_NXT1 ; NOT AT END YET +; + LD HL,MD_FFMSGUNK ; WE REACHED THE END WITHOUT A MATCH +; +FF_NXT2: +#IF (MD_FVBS==1) + CALL PRTSTR ; AFTER SEARCH DISPLAY THE RESULT +#ENDIF + RET +; +;====================================================================== +; COMMON FUNCTION CALL FOR: +; +; MD_FIDEN_R - IDENTIFY FLASH CHIP +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; ON EXIT BC CONTAINS THE CHIP ID BYTES. +; A NO STATUS IS RETURNED +; +; MD_FERAS_R - ERASE FLASH SECTOR +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; ON EXIT A RETURNS STATUS 0=SUCCESS NZ=FAIL +; +; MD_FREAD_R - READ FLASH SECTOR +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; IX POINTS TO WHERE TO SAVE DATA +; ON EXIT A NO STATUS IS RETURNED +; +; MD_FVERI_R - VERIFY FLASH SECTOR +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; IX POINTS TO DATA TO COMPARE. +; ON EXIT A RETURNS STATUS 0=SUCCESS NZ=FAIL +; +; MD_FWRIT_R - WRITE FLASH SECTOR +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; IX POINTS TO DATA TO BE WRITTEN +; ON EXIT A NO STATUS IS RETURNED +; +; GENERAL OPERATION: +; COPY FLASH CODE TO CODE BUFFER +; CALL RELOCATED FLASH CODE +; RETURN WITH ID CODE. +;====================================================================== +; +MD_FNCALL: ; USING HBX_BUF FOR CODE AREA +; + LD B,0 ; RETREIVE THE + DEC HL ; CODE SIZE TO + LD C,(HL) ; BE COPIED + INC HL ; MAXIMUM 64 BYTES +; + LD DE,HBX_BUF ; EXECUTE / START ADDRESS + LDIR ; COPY OUR RELOCATABLE CODE TO THE BUFFER +; + LD D,B ; PRESET DE TO ZERO TO REDUCE + LD E,B ; CODE SIZE IN RELOCATABLE CODE +; + LD BC,(MD_FBAS) ; PUT BANK AND SECTOR DATA IN BC +; +#IF (MD_FDBG==1) + CALL PRTHEXWORD +#ENDIF +; + LD A,(HB_CURBNK) ; WE ARE STARTING IN HB_CURBNK +; + HB_DI + LD (MD_SAVSTK),SP ; SAVE CURRENT STACK + LD SP,HBX_BUF_END ; SETUP A NEW HIMEM STACK AT END OF HX_BUF + CALL HBX_BUF ; EXECUTE RELOCATED CODE + LD SP,(MD_SAVSTK) ; RESTORE STACK + HB_EI +; +#IF (MD_FDBG==1) + CALL PC_SPACE + CALL PRTHEXWORD + CALL PC_SPACE + EX DE,HL + CALL PRTHEXWORDHL + CALL PC_SPACE + EX DE,HL +#ENDIF +; + LD A,C ; RETURN WITH STATUS IN A + RET ; RETURN TO MD_READF, MD_WRITEF +; +MD_SAVSTK .DW 0 +; +#INCLUDE "flashlib.inc" +; +;====================================================================== +; +; FLASH CHIP LIST +; +;====================================================================== +; +#DEFINE FF_CHIP(FFROMID,FFROMNM) \ +#DEFCONT ; \ +#DEFCONT .DW FFROMID \ +#DEFCONT .DB FFROMNM \ +#DEFCONT ; +; +MD_TABLE: +FF_CHIP(00120H,"29F010$ ") +FF_CHIP(001A4H,"29F040$ ") +FF_CHIP(01F04H,"AT49F001NT$") +FF_CHIP(01F05H,"AT49F001N$ ") +FF_CHIP(01F07H,"AT49F002N$ ") +FF_CHIP(01F08H,"AT49F002NT$") +FF_CHIP(01F13H,"AT49F040$ ") +FF_CHIP(01F5DH,"AT29C512$ ") +FF_CHIP(01FA4H,"AT29C040$ ") +FF_CHIP(01FD5H,"AT29C010$ ") +FF_CHIP(01FDAH,"AT29C020$ ") +FF_CHIP(02020H,"M29F010$ ") +FF_CHIP(020E2H,"M29F040$ ") +FF_CHIP(0BFB5H,"39F010$ ") +FF_CHIP(0BFB6H,"39F020$ ") +FF_CHIP(0BFB7H,"39F040$ ") +FF_CHIP(0C2A4H,"MX29F040$ ") +; +MD_T_CNT .EQU 17 +MD_T_SZ .EQU ($-MD_TABLE) / MD_T_CNT +MD_FFMSGUNK .DB "UNKNOWN$" +MD_FFMSGDIS .DB "DISABLED$" +MD_FFMSGENA .DB "ENABLED$" +; +;====================================================================== +; +; 4K FLASH SECTOR BUFFER +; +;====================================================================== +; +MD_F4KBUF .FILL 4096,$FF +MD_FFSEN .DB 00h ; FLASH FILES SYSTEM ENABLE +; +#ENDIF +; +MD_RWFNADR .DW 0 +MD_DSKBUF .DW 0 MD_SRCBNK .DB 0 MD_DSTBNK .DB 0 MD_SRC .DW 0 MD_DST .DW 0 MD_LEN .DW 0 -; -MDSTR_PREFIX .TEXT "MD:$" -MDSTR_SRC .TEXT "SRC=$" -MDSTR_DST .TEXT "DEST=$" -MDSTR_LEN .TEXT "LEN=$" \ No newline at end of file diff --git a/Source/HBIOS/nascom.asm b/Source/HBIOS/nascom.asm index 1449c741..6b9e7297 100644 --- a/Source/HBIOS/nascom.asm +++ b/Source/HBIOS/nascom.asm @@ -4715,9 +4715,13 @@ MONOUT: POP AF RET -MONITR: LD A,BID_BOOT ; BOOT BANK - LD HL,0 ; ADDRESS ZERO - CALL HB_BNKCALL ; DOES NOT RETURN +MONITR: ;LD A,BID_BOOT ; BOOT BANK + ;LD HL,0 ; ADDRESS ZERO + ;CALL HB_BNKCALL ; DOES NOT RETURN + + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_WARM ; WARM START + CALL $FFF0 ; CALL HBIOS INITST: LD A,0 ; Clear break flag LD (BRKFLG),A diff --git a/Source/HBIOS/pio.asm b/Source/HBIOS/pio.asm index 349858a2..c0d230f7 100644 --- a/Source/HBIOS/pio.asm +++ b/Source/HBIOS/pio.asm @@ -720,6 +720,8 @@ PPI_DEVICE: LD D,CIODEV_PIO ; D := DEVICE TYPE LD E,(IY) ; E := PHYSICAL UNIT LD C,$40 ; C := ATTRIBUTE + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+3) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; diff --git a/Source/HBIOS/ppide.asm b/Source/HBIOS/ppide.asm index 637ed394..e87a3a64 100644 --- a/Source/HBIOS/ppide.asm +++ b/Source/HBIOS/ppide.asm @@ -470,7 +470,10 @@ PPIDE_FNTBL: PPIDE_VERIFY: PPIDE_FORMAT: PPIDE_DEFMED: - CALL PANIC ; NOT IMPLEMENTED + CALL SYSCHK ; NOT IMPLEMENTED + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -529,7 +532,10 @@ PPIDE_IO3: LD E,C ; SECTOR READ COUNT TO E LD HL,(PPIDE_DSKBUF) ; CURRENT DMA TO HL OR A ; SET FLAGS BASED ON RETURN CODE - RET ; AND RETURN, A HAS RETURN CODE + RET Z ; RETURN IF SUCCESS + LD A,ERR_IO ; SIGNAL IO ERROR + OR A ; SET FLAGS + RET ; AND DONE ; ; ; @@ -549,6 +555,8 @@ PPIDE_DEVICE: JR Z,PPIDE_DEVICE1 ; IF Z, WE ARE DONE LD C,%01001000 ; OTHERWISE REMOVABLE COMPACT FLASH PPIDE_DEVICE1: + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+PPIDE_DATALO) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -583,6 +591,8 @@ PPIDE_MEDIA2: LD E,MID_HD ; ASSUME WE ARE OK RET Z ; RETURN IF GOOD INIT LD E,MID_NONE ; SIGNAL NO MEDIA + LD A,ERR_NOMEDIA ; NO MEDIA ERROR + OR A ; SET FLAGS RET ; AND RETURN ; ; @@ -974,6 +984,27 @@ PPIDE_RESET: CALL PPIDE_PRTPREFIX PRTS(" RESET$") #ENDIF +; + ; OLDER CF CARDS DO NOT SEEM TO SET THE + ; REGISTERS ON RESET, SO HERE WE FAKE THINGS BY + ; SETTING THEM AS A RESET WOULD +#IF (PPIDETRACE >= 3) + PRTS(" FAKE$") +#ENDIF + XOR A + ;OUT (IDE_IO_CYLLO),A + CALL PPIDE_OUT + .DB PPIDE_REG_CYLLO + ;OUT (IDE_IO_CYLHI),A + CALL PPIDE_OUT + .DB PPIDE_REG_CYLHI + INC A + ;OUT (IDE_IO_COUNT),A + CALL PPIDE_OUT + .DB PPIDE_REG_COUNT + ;OUT (IDE_IO_SECT),A + CALL PPIDE_OUT + .DB PPIDE_REG_SECT ; ; SETUP PPI TO READ LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ diff --git a/Source/HBIOS/ppp.asm b/Source/HBIOS/ppp.asm index 0b45b1eb..ff395002 100644 --- a/Source/HBIOS/ppp.asm +++ b/Source/HBIOS/ppp.asm @@ -338,7 +338,10 @@ PPPCON_OST: ; ; PPPCON_INITDEV: - CALL PANIC + CALL SYSCHK + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -354,6 +357,8 @@ PPPCON_DEVICE: LD D,CIODEV_PPPCON ; D := DEVICE TYPE LD E,0 ; E := DEVICE NUM, ALWAYS 0 LD C,$BF ; C := DEVICE TYPE, 0xBF IS PROP TERM + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,PPIBASE ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -499,7 +504,10 @@ PPPSD_FNTBL: PPPSD_VERIFY: PPPSD_FORMAT: PPPSD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL SYSCHK ; INVALID SUB-FUNCTION + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -566,8 +574,11 @@ PPPSD_IO2: PPPSD_IO3: LD E,C ; SECTOR READ COUNT TO E LD HL,(PPPSD_DSKBUF) ; CURRENT BUF ADR TO HL + OR A ; SET FLAGS BASED ON RETURN CODE + RET Z ; RETURN IF SUCCESS + LD A,ERR_IO ; SIGNAL IO ERROR OR A ; SET FLAGS - RET ; RETURN WITH A = STATUS + RET ; AND DONE ; ; ; @@ -682,6 +693,8 @@ PPPSD_DEVICE: LD D,DIODEV_PPPSD ; D := DEVICE TYPE LD E,(IY+PPPSD_DEV) ; E := PHYSICAL DEVICE NUMBER LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,PPIBASE ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -697,6 +710,8 @@ PPPSD_MEDIA: LD E,MID_HD ; ASSUME WE ARE OK RET Z ; RETURN IF GOOD INIT LD E,MID_NONE ; SIGNAL NO MEDA + LD A,ERR_NOMEDIA ; NO MEDIA ERROR + OR A ; SET FLAGS RET ; AND RETURN ; ; diff --git a/Source/HBIOS/prp.asm b/Source/HBIOS/prp.asm index bb95606f..cea20545 100644 --- a/Source/HBIOS/prp.asm +++ b/Source/HBIOS/prp.asm @@ -211,7 +211,10 @@ PRPCON_OST1: ; ; PRPCON_INITDEV: - CALL PANIC + CALL SYSCHK + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -227,6 +230,8 @@ PRPCON_DEVICE: LD D,CIODEV_PRPCON ; D := DEVICE TYPE LD E,0 ; E := DEVICE NUM, ALWAYS 0 LD C,$BF ; C := DEVICE TYPE, 0xBF IS PROP TERM + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,PRP_IOBASE ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -396,7 +401,10 @@ PRPSD_FNTBL: PRPSD_VERIFY: PRPSD_FORMAT: PRPSD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL SYSCHK ; INVALID SUB-FUNCTION + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -463,8 +471,11 @@ PRPSD_IO2: PRPSD_IO3: LD E,C ; SECTOR READ COUNT TO E LD HL,(PRPSD_DSKBUF) ; CURRENT BUF ADR TO HL + OR A ; SET FLAGS BASED ON RETURN CODE + RET Z ; RETURN IF SUCCESS + LD A,ERR_IO ; SIGNAL IO ERROR OR A ; SET FLAGS - RET ; RETURN WITH A = STATUS + RET ; AND DONE ; ; ; @@ -539,6 +550,8 @@ PRPSD_DEVICE: LD D,DIODEV_PRPSD ; D := DEVICE TYPE LD E,(IY+PRPSD_DEV) ; E := PHYSICAL DEVICE NUMBER LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,PRP_IOBASE ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -553,6 +566,8 @@ PRPSD_MEDIA: LD E,MID_HD ; ASSUME WE ARE OK RET Z ; RETURN IF GOOD INIT LD E,MID_NONE ; SIGNAL NO MEDA + LD A,ERR_NOMEDIA ; NO MEDIA ERROR + OR A ; SET FLAGS RET ; AND RETURN ; ; diff --git a/Source/HBIOS/rf.asm b/Source/HBIOS/rf.asm index 2ecba90f..282a962e 100644 --- a/Source/HBIOS/rf.asm +++ b/Source/HBIOS/rf.asm @@ -138,7 +138,10 @@ RF_FNTBL: RF_VERIFY: RF_FORMAT: RF_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL SYSCHK ; INVALID SUB-FUNCTION + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -178,6 +181,8 @@ RF_DEVICE: LD D,DIODEV_RF ; D := DEVICE TYPE LD E,(IY+RF_DEV) ; E := PHYSICAL DEVICE NUMBER LD C,%00110000 ; C := ATTRIBUTES, NON-REMOVABLE RAM FLOPPY + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+RF_IOAD) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -219,7 +224,8 @@ RF_WRITE: CALL RF_CHKWP ; WRITE PROTECTED? JR Z,RF_RW ; IF 0, NOT WP, CONTINUE WITH GENERIC R/W ROUTINE LD E,0 ; ZERO SECTORS WRITTEN - OR $FF ; SIGNAL ERROR + LD A,ERR_READONLY ; SIGNAL ERROR + OR A ; SET FLAGS RET ; AND DONE ; ; @@ -255,7 +261,10 @@ RF_RW3: LD E,C ; SECTOR READ COUNT TO E LD HL,(RF_DSKBUF) ; CURRENT DMA TO HL OR A ; SET FLAGS BASED ON RETURN CODE - RET ; AND RETURN, A HAS RETURN CODE + RET Z ; RETURN SUCCESS + LD A,ERR_IO ; SIGNAL IO ERROR + OR A ; SET FLAGS + RET ; AND DONE ; ; READ SECTOR ; diff --git a/Source/HBIOS/romldr.asm b/Source/HBIOS/romldr.asm index 747dd032..17783fa4 100644 --- a/Source/HBIOS/romldr.asm +++ b/Source/HBIOS/romldr.asm @@ -106,7 +106,7 @@ bid_cur .equ -1 ; used below to indicate current bank ; start: ld sp,bl_stack ; setup private stack - call DELAY_INIT ; init delay functions + call delay_init ; init delay functions ; ; Disable interrupts if IM1 is active because we are switching to page ; zero in user bank and it has not been prepared with IM1 vector yet. @@ -123,7 +123,7 @@ start: rst 08 ; do it ld a,c ; previous bank to A ld (bid_ldr),a ; save previous bank for later - cp BID_IMG0 ; starting from ROM? + bit 7,a ; starting from ROM? #endif ; #if (BIOS == BIOS_UNA) @@ -131,8 +131,7 @@ start: ld de,BID_USR ; select user bank rst 08 ; do it ld (bid_ldr),de ; ... for later - ld a,d ; starting from ROM? - or e ; ... bank == 0? + bit 7,d ; starting from ROM? #endif ; ; For app mode startup, use alternate table @@ -146,7 +145,7 @@ start1: ; ld hl,$8000 ; page zero was copied here ld de,0 ; put it in user page zero - ld bc,$100 ; full page + ld bc,$100 ; full page ldir ; do it ; ; Page zero in user bank is ready for interrupts now. @@ -164,20 +163,22 @@ start1: call pstr ; do it call clrbuf ; zero fill the cmd buffer ; -#if (BOOT_TIMEOUT > 0) +#if (BOOT_TIMEOUT != -1) ; Initialize auto command timeout downcounter or $FF ; auto cmd active value ld (acmd_act),a ; set flag ld bc,BOOT_TIMEOUT * 100 ; hundredths of seconds ld (acmd_to),bc ; save auto cmd timeout - ;ld a,b ; check for - ;or c ; ... zero - ;jr nz,prompt ; not zero, prompt w/ timeout - ;call nl2 ; formatting - ;ld hl,str_boot ; command string prefix - ;call pstr ; show it - ;call autocmd ; else, handle w/o prompt - ;jr reprompt ; restart w/ autocmd disable +; + ; If timeout is zero, boot auto command immediately + ld a,b ; check for + or c ; ... zero + jr nz,prompt ; not zero, prompt w/ timeout + call nl2 ; formatting + ld hl,str_autoboot ; auto command prefix + call pstr ; show it + call autocmd ; handle w/o prompt + jr reprompt ; restart w/ autocmd disable #endif ; prompt: @@ -205,7 +206,7 @@ wtkey: jp nz,dskycmd ; if pending, do DSKY command #endif ; -#if (BOOT_TIMEOUT > 0) +#if (BOOT_TIMEOUT != -1) ; check for timeout and handle auto boot here ld a,(acmd_act) ; get auto cmd active flag or a ; set flags @@ -217,7 +218,7 @@ wtkey: dec bc ; decrement ld (acmd_to),bc ; resave it ld de,625 ; 16us * 625 = 10ms - call VDELAY ; 10ms delay + call vdelay ; 10ms delay #endif ; jr wtkey ; loop @@ -281,6 +282,12 @@ runcmd: jp z,devlst ; if so, do it cp 'R' ; R = reboot system jp z,reboot ; if so, do it +#if (BIOS == BIOS_WBW) + cp 'I' ; C = set console interface + jp z,setcon ; if so, do it + cp 'V' ; V = diagnostic verbosity + jp z,setdl ; is so, do it +#endif ; ; Attempt ROM application launch ld ix,(ra_tbl_loc) ; point to start of ROM app tbl @@ -334,7 +341,7 @@ runcmd2: dskycmd: call clrled ; clear LEDs ; - call DSKY_GETKEY ; get DSKY key + call DSKY_GETKEY ; get DSKY key cp $FF ; check for error ret z ; abort if so ; @@ -422,24 +429,152 @@ devlst: call pstr ; display it jp prtall ; do it ; +; Set console interface unit +; +#if (BIOS == BIOS_WBW) +; +setcon: + ; On entry DE is expected to be pointing to start + ; of command. Get unit number. + call findws ; skip command + call skipws ; and skip it + call isnum ; do we have a number? + jp nz,err_invcmd ; if not, invalid + call getnum ; parse number into A + jp c,err_nocon ; handle overflow error +; + ; Check against max char unit + push de + push af ; save requested unit + ld b,BF_SYSGET ; HBIOS func: SYS GET + ld c,BF_SYSGET_CIOCNT ; HBIOS subfunc: CIO unit count + rst 08 ; E := unit count + pop af ; restore requested unit + cp e ; compare + pop de + jp nc,err_nocon ; handle invalid unit + ld (newcon),a ; save validated console +; + ; Get baud rate + call findws + call skipws ; skip whitespace + call isnum ; do we have a number? + jp nz,docon ; if no we don't change baudrate + call getnum ; parse a number + jp c,err_invcmd ; handle overflow error +; + cp 32 ; handle invalid + jp nc,err_invcmd ; baud rate + bit 0,a + jr z,iseven ; convert sequential + inc a ; baud rate code to + srl a ; encoded baud rate + jr setspd ; 13=9600 +iseven: dec a ; 15=19200 + srl a ; 17=38400 + add a,16 ; 20=115200 +setspd: ld (newspeed),a ; save validated baud rate +; + ld hl,str_chspeed ; notify user + call pstr ; to change + call cin ; speed +; + ; Get the current settings for chosen console + ld b,BF_CIOQUERY ; BIOS serial device query + ld a,(newcon) ; get device unit num + ld c,a ; ... and put in C + rst 08 ; call H/UBIOS, DE := line characteristics + jp nz,err_invcmd ; abort on error +; + ld a,d ; mask off current + and $11100000 ; baud rate + ld hl,newspeed ; and load in new + or (hl) ; baud rate + ld d,a +; + ld b,BF_CIOINIT ; BIOS serial init + ld a,(newcon) ; get serial device unit + ld c,a ; ... into C + rst 08 ; call HBIOS + jp nz,err_invcmd ; handle error +; + ; Notify user, we're outta here.... +docon: ld hl,str_newcon ; new console msg + call pstr ; print string on cur console + ld a,(newcon) ; restore new console unit + call prtdecb ; print unit num +; + ; Set console unit + ld b,BF_SYSPOKE ; HBIOS func: POKE + ld d,BID_BIOS ; BIOS bank + ld e,a ; Char unit value + ld hl,HCB_LOC + HCB_CONDEV ; Con unit num in HCB + rst 08 ; do it +; + ; Display loader prompt on new console + call nl2 ; formatting + ld hl,str_banner ; display boot banner + call pstr ; do it + ret ; done +; +#endif +; +; Set RomWBW HBIOS Diagnostic Level +; +#if (BIOS == BIOS_WBW) +; +setdl: + ; On entry DE is expected to be pointing to start + ; of command + call findws ; skip command + call skipws ; and skip it + or a ; set flags to check for null + jr z,showdl ; no parm, just display + call isnum ; do we have a number? + jp nz,err_invcmd ; if not, invalid + call getnum ; parse number into A + jp c,err_invcmd ; handle overflow error +; + ; Set diagnostic level + ld b,BF_SYSPOKE ; HBIOS func: POKE + ld d,BID_BIOS ; BIOS bank + ld e,a ; diag level value + ld hl,HCB_LOC + HCB_DIAGLVL ; offset into HCB + rst 08 ; do it + ; Fall thru to display new value +; +showdl: + ; Display current diagnostic level + ld hl,str_diaglvl ; diag level tag + call pstr ; print it + ld b,BF_SYSPEEK ; HBIOS func: PEEK + ld d,BID_BIOS ; BIOS bank + ld hl,HCB_LOC + HCB_DIAGLVL ; offset into HCB + rst 08 ; do it, E := level value + ld a,e ; put in accum + call prtdecb ; print it + ret ; done +; +#endif +; ; Restart system ; reboot: ld hl,str_reboot ; point to message call pstr ; print it - call LDELAY ; wait for message to display + call ldelay ; wait for message to display ; #if (BIOS == BIOS_WBW) ; #if (DSKYENABLE) ld hl,msg_boot ; point to boot message - call DSKY_SHOWSEG ; display message + call DSKY_SHOWSEG ; display message #endif ; - ; switch to rom bank 0 and jump to address 0 - ld a,BID_BOOT ; boot bank - ld hl,0 ; address zero - call HB_BNKCALL ; does not return + ; cold boot system + ld b,BF_SYSRESET ; system restart + ld c,BF_SYSRES_COLD ; cold start + rst 08 ; do it, no return #endif ; #if (BIOS == BIOS_UNA) @@ -465,7 +600,7 @@ romload: ; #if (DSKYENABLE) ld hl,msg_load ; point to load message - call DSKY_SHOWSEG ; display message + call DSKY_SHOWSEG ; display message #endif ; #if (BIOS == BIOS_WBW) @@ -509,9 +644,9 @@ romload1: #if (BIOS == BIOS_UNA) ; ; Note: UNA has no interbank memory copy, so we can only load -; images from the current bank. We switch to the original bank +; images from the current bank. We switch to the original bank ; use a simple ldir to relocate the image, then switch back to the -; user bank to launch. This will only work if the images are in +; user bank to launch. This will only work if the images are in ; the lower 32K and the relocation adr is in the upper 32K. ; ; Switch to original bank @@ -549,7 +684,7 @@ romload1: ; #if (DSKYENABLE) ld hl,msg_go ; point to go message - call DSKY_SHOWSEG ; display message + call DSKY_SHOWSEG ; display message #endif ; ld l,(ix+ra_ent) ; HL := app entry address @@ -566,27 +701,36 @@ diskboot: ld hl,str_boot1 call pstr ld a,(bootunit) - call PRTDECB + call prtdecb ld hl,str_boot2 call pstr ld a,(bootslice) - call PRTDECB + call prtdecb ; #if (DSKYENABLE) ld hl,msg_load ; point to load message - call DSKY_SHOWSEG ; display message + call DSKY_SHOWSEG ; display message #endif ; #if (BIOS == BIOS_WBW) ; ; Check that drive actually exists - ld c,a ; put in C for func call ld b,BF_SYSGET ; HBIOS func: sys get ld c,BF_SYSGET_DIOCNT ; HBIOS sub-func: disk count rst 08 ; do it, E=disk count ld a,(bootunit) ; get boot disk unit cp e ; compare to count jp nc,err_nodisk ; handle no disk err +; + ; Sense media + ld a,(bootunit) ; get boot disk unit + ld c,a ; put in C for func call + ld b,BF_DIOMEDIA ; HBIOS func: media + ld e,1 ; enable media check/discovery + rst 08 ; do it + jp nz,err_diskio ; handle error + ld a,e ; media id to A + ld (mediaid),a ; save media id ; ; If non-zero slice requested, confirm device can handle it ld a,(bootslice) ; get slice @@ -600,40 +744,6 @@ diskboot: cp DIODEV_IDE ; IDE is max slice device type jp c,err_noslice ; no such slice, handle err ; -diskboot1: - ; Sense media - ld a,(bootunit) ; get boot disk unit - ld c,a ; put in C for func call - ld b,BF_DIOMEDIA ; HBIOS func: media - ld e,1 ; enable media check/discovery - rst 08 ; do it - jp nz,err_diskio ; handle error - call pdot ; show progress -; - ; Seek to boot info sector, third sector - ld a,(bootslice) ; get boot slice - ld e,a ; move to E for mult - ld h,65 ; 65 tracks per slice - call MULT8 ; hl := h * e - ld de,$0002 ; head 0, sector 2 - ld b,BF_DIOSEEK ; HBIOS func: seek - ld a,(bootunit) ; get boot disk unit - ld c,a ; put in C - rst 08 ; do it - jp nz,err_diskio ; handle error - call pdot ; show progress -; - ; Read sector into local buffer - ld b,BF_DIOREAD ; HBIOS func: disk read - ld a,(bootunit) ; get boot disk unit - ld c,a ; put in C for func call - ld hl,bl_infosec ; read into info sec buffer - ld d,BID_USR ; user bank - ld e,1 ; transfer one sector - rst 08 ; do it - jp nz,err_diskio ; handle error - call pdot ; show progress -; #endif ; #if (BIOS == BIOS_UNA) @@ -648,59 +758,129 @@ diskboot1: ; If non-zero slice requested, confirm device can handle it ld a,(bootslice) ; get slice or a ; set flags - jr z,diskboot1 ; slice 0, skip slice check + jr z,diskboot0 ; slice 0, skip slice check ld a,d ; disk type to A cp $41 ; IDE? - jr z,diskboot1 ; if so, OK + jr z,diskboot0 ; if so, OK cp $42 ; PPIDE? - jr z,diskboot1 ; if so, OK + jr z,diskboot0 ; if so, OK cp $43 ; SD? - jr z,diskboot1 ; if so, OK + jr z,diskboot0 ; if so, OK cp $44 ; DSD? - jr z,diskboot1 ; if so, OK + jr z,diskboot0 ; if so, OK jp err_noslice ; no such slice, handle err ; +diskboot0: + ; Below is wrong. It assumes we are booting from a hard + ; disk, but it could also be a RAM/ROM disk. However, it is + ; not actually possible to boot from those, so not gonna + ; worry about this. + ld a,4 ; assume legacy hard disk + ld (mediaid),a ; save media id +; +#endif +; diskboot1: + ; Initialize working LBA value + ld hl,0 ; zero HL + ld (lba),hl ; init + ld (lba+2),hl ; ... LBA +; + ; Set legacy sectors per slice + ld hl,16640 ; legacy sectors per slice + ld (sps),hl ; save it +; + ; Check for hard disk + ld a,(mediaid) ; load media id + cp 4 ; legacy hard disk? + jr nz,diskboot8 ; if not hd, no part table +; + ; Attempt to read MBR + ld de,0 ; MBR is at + ld hl,0 ; ... first sector + ld bc,bl_mbrsec ; read into MBR buffer + ld (dma),bc ; save + ld b,1 ; one sector + ld a,(bootunit) ; get bootunit + ld c,a ; put in C + call diskread ; do it + ret nz ; abort on error +; + ; Check signature + ld hl,(bl_mbrsec+$1FE) ; get signature + ld a,l ; first byte + cp $55 ; should be $55 + jr nz,diskboot4 ; if not, no part table + ld a,h ; second byte + cp $AA ; should be $AA + jr nz,diskboot4 ; if not, no part table +; + ; Try to find our entry in part table and capture lba offset + ld b,4 ; four entries in part table + ld hl,bl_mbrsec+$1BE+4 ; offset of first entry part type +diskboot2: + ld a,(hl) ; get part type + cp $2E ; cp/m partition? + jr z,diskboot3 ; cool, grab the lba offset + ld de,16 ; part table entry size + add hl,de ; bump to next entry part type + djnz diskboot2 ; loop thru table + jr diskboot4 ; too bad, no cp/m partition +; +diskboot3: + ; Capture the starting LBA of the CP/M partition we found + ld de,4 ; LBA is 4 bytes after part type + add hl,de ; point to it + ld de,lba ; loc to store lba offset + ld bc,4 ; 4 bytes (32 bits) + ldir ; copy it + ; If boot from partition, use new sectors per slice value + ld hl,16384 ; new sectors per slice + ld (sps),hl ; save it +; +diskboot4: ; Add slice offset ld a,(bootslice) ; get boot slice, A is loop cnt - ld hl,0 ; DE:HL is LBA - ld de,0 ; ... initialize to zero - ld bc,16640 ; sectors per slice -diskboot2: + ld hl,(lba) ; set DE:HL + ld de,(lba+2) ; ... to starting LBA + ld bc,(sps) ; sectors per slice +diskboot5: or a ; set flags to check loop ctr - jr z,diskboot4 ; done if counter exhausted + jr z,diskboot7 ; done if counter exhausted add hl,bc ; add one slice to low word - jr nc,diskboot3 ; check for carry + jr nc,diskboot6 ; check for carry inc de ; if so, bump high word -diskboot3: +diskboot6: dec a ; dec loop downcounter - jr diskboot2 ; and loop + jr diskboot5 ; and loop ; -diskboot4: - ld (loadlba),hl ; save lba, low word - ld (loadlba+2),de ; save lba, high word +diskboot7: + ld (lba),hl ; update lba, low word + ld (lba+2),de ; update lba, high word +; +diskboot8: + ; Note that we could be coming from diskboot1! + ld hl,str_ldsec ; display prefix + call pstr ; do it + ld hl,(lba) ; recover lba loword + ld de,(lba+2) ; recover lba hiword + call prthex32 ; display starting sector + call pdot ; show progress ; - ; Seek to boot info sector, third sector + ; Read boot info sector, third sector ld bc,2 ; sector offset add hl,bc ; add to LBA value low word - jr nc,diskboot5 ; check for carry + jr nc,diskboot9 ; check for carry inc de ; if so, bump high word -diskboot5: - ld a,(bootunit) ; get disk unit to boot - ld b,a ; put in B for func call - ld c,$41 ; UNA func: set lba - rst 08 ; set lba - jp nz,err_api ; handle error +diskboot9: + ld bc,bl_infosec ; read buffer + ld (dma),bc ; save + ld a,(bootunit) ; disk unit to read + ld c,a ; put in C + ld b,1 ; one sector + call diskread ; do it + ret nz ; abort on error call pdot ; show progress -; - ; Read sector into local buffer - ld c,$42 ; UNA func: read sectors - ld de,bl_infosec ; dest of cpm image - ld l,1 ; sectors to read - rst 08 ; do read - jp nz,err_diskio ; handle error -; -#endif ; ; Check signature ld de,(bb_sig) ; get signature read @@ -710,6 +890,7 @@ diskboot5: ld a,$5A ; expected value of second byte cp e ; compare jp nz,err_sig ; handle error + call pdot ; show progress ; ; Print disk boot info ; Volume "xxxxxxx" (0xXXXX-0xXXXX, entry @ 0xXXXX) @@ -722,43 +903,53 @@ diskboot5: call pstr ; print push hl ; save string ptr ld bc,(bb_cpmloc) ; get load loc - call PRTHEXWORD ; print it + call prthexword ; print it pop hl ; restore string ptr call pstr ; print push hl ; save string ptr ld bc,(bb_cpmend) ; get load end - call PRTHEXWORD ; print it + call prthexword ; print it pop hl ; restore string ptr call pstr ; print push hl ; save string ptr ld bc,(bb_cpment) ; get load end - call PRTHEXWORD ; print it + call prthexword ; print it pop hl ; restore string ptr call pstr ; print ; ; Compute number of sectors to load ld hl,(bb_cpmend) ; hl := end - ld de,(bb_cpmloc) ; de := start + ld de,(bb_cpmloc) ; de := start or a ; clear carry sbc hl,de ; hl := length to load + ; If load length is not a multiple of sector size (512) + ; we need to round up to get everything loaded! + ld de,511 ; 1 less than sector size + add hl,de ; ... and roundup ld a,h ; determine 512 byte sector count rra ; ... by dividing msb by two ld (loadcnt),a ; ... and save it call pdot ; show progress ; -#if (BIOS == BIOS_WBW) -; - ; Load image into memory - ld b,BF_DIOREAD ; HBIOS func: read sectors + ; Start OS load at sector 3 + ld hl,(lba) ; low word of saved LBA + ld de,(lba+2) ; high word of saved LBA + ld bc,3 ; offset for sector 3 + add hl,bc ; apply it + jr nc,diskboot10 ; check for carry + inc de ; bump high word if so +diskboot10: + ld bc,(bb_cpmloc) ; load address + ld (dma),bc ; and save it + ld a,(loadcnt) ; get sectors to read + ld b,a ; put in B ld a,(bootunit) ; get boot disk unit ld c,a ; put in C - ld hl,(bb_cpmloc) ; load address - ld d,BID_USR ; user bank - ld a,(loadcnt) ; get sectors to read - ld e,a ; number of sectors to load - rst 08 ; do it - jp nz,err_diskio ; handle errors + call diskread ; read image + ret nz ; abort on error call pdot ; show progress +; +#if (BIOS == BIOS_WBW) ; ; Record boot unit/slice ld b,BF_SYSSET ; hb func: set hbios parameter @@ -771,36 +962,10 @@ diskboot5: ld e,a ; save in E rst 08 jp nz,err_api ; handle errors - call pdot ; show progress ; #endif ; #if (BIOS == BIOS_UNA) -; - ; Start os load at sector 3 - ld hl,(loadlba) ; low word of saved LBA - ld de,(loadlba+2) ; high word of saved LBA - ld bc,3 ; offset for sector 3 - add hl,bc ; apply it - jr nc,diskboot6 ; check for carry - inc de ; bump high word if so -diskboot6: - ld c,$41 ; UNA func: set lba - ld a,(bootunit) ; get boot disk unit - ld b,a ; move to B - rst 08 ; set lba - jp nz,err_api ; handle error -; - ; Read OS image into memory - ld c,$42 ; UNA func: read sectors - ld a,(bootunit) ; get boot disk unit - ld b,a ; move to B - ld de,(bb_cpmloc) ; dest of cpm image - ld a,(loadcnt) ; get sectors to read - ld l,a ; sectors to read - rst 08 ; do read - jp nz,err_diskio ; handle error - call pdot ; show progress ; ; Record boot unit/slice ; UNA provides only a single byte to record the boot unit @@ -821,19 +986,69 @@ diskboot6: ld bc,$01FC ; UNA func: set bootstrap hist rst 08 ; call UNA jp nz,err_api ; handle error - call pdot ; show progress ; #endif +; + call pdot ; show progress ; #if (DSKYENABLE) ld hl,msg_go ; point to go message - call DSKY_SHOWSEG ; display message + call DSKY_SHOWSEG ; display message #endif ; ; Jump to entry vector ld hl,(bb_cpment) ; get entry vector jp (hl) ; and go there ; +; Read disk sector(s) +; DE:HL is LBA, B is sector count, C is disk unit +; +diskread: +; +#if (BIOS == BIOS_UNA) +; + ; Seek to requested sector in DE:HL + push bc ; save unit and count + ld b,c ; unit to read in B + ld c,$41 ; UNA func: set lba + rst 08 ; set lba + pop bc ; recover unit and count + jp nz,err_api ; handle error +; + ; Read sector(s) into buffer + ld l,b ; sectors to read + ld b,c ; unit to read in B + ld c,$42 ; UNA func: read sectors + ld de,(dma) ; dest for read + rst 08 ; do read + jp nz,err_diskio ; handle error + xor a ; signal success + ret ; and done +; +#endif +; +#if (BIOS == BIOS_WBW) +; + ; Seek to requested sector in DE:HL + push bc ; save unit & count + set 7,d ; set LBA access flag + ld b,BF_DIOSEEK ; HBIOS func: seek + rst 08 ; do it + pop bc ; recover unit & count + jp nz,err_diskio ; handle error +; + ; Read sector(s) into buffer + ld e,b ; transfer count + ld b,BF_DIOREAD ; HBIOS func: disk read + ld hl,(dma) ; read into info sec buffer + ld d,BID_USR ; user bank + rst 08 ; do it + jp nz,err_diskio ; handle error + xor a ; signal success + ret ; and done +; +#endif +; ;======================================================================= ; Utility functions ;======================================================================= @@ -928,7 +1143,7 @@ rdln_nxt: jr rdln_nxt ; loop till done ; rdln_bs: - ld hl,cmdbuf ; start of buffer + ld hl,cmdbuf ; start of buffer or a ; clear carry sbc hl,de ; subtract from cur buf ptr jr z,rdln_bel ; at buf start, just beep @@ -947,16 +1162,29 @@ rdln_cr: ld (de),a ; store terminator ret ; and return ; +; Find next whitespace character at buffer adr in DE, returns with first +; whitespace character in A. +; +findws: + ld a,(de) ; get next char + or a ; check for eol + ret z ; done if so + cp ' ' ; blank? + ret z ; nope, done + inc de ; bump buffer pointer + jr findws ; and loop +; ; Skip whitespace at buffer adr in DE, returns with first ; non-whitespace character in A. ; skipws: ld a,(de) ; get next char + or a ; check for eol + ret z ; done if so cp ' ' ; blank? ret nz ; nope, done inc de ; bump buffer pointer jr skipws ; and loop - ; ; Uppercase character in A ; @@ -1018,6 +1246,269 @@ isnum1: or $FF ; set NZ ret ; and done ; +; 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 +; HBIOS *must* be installed and available via rst 8!!! +; CPU scaler := max(1, (phimhz - 2)) +; +delay_init: +#if (BIOS == BIOS_UNA) + ld c,$F8 ; UNA bios get phi function + rst 08 ; returns speed in hz in de:hl + ld b,4 ; divide mhz in de:hl by 100000h +delay_init0: + srl d ; ... to get approx cpu speed in + rr e ; ...mhz. throw away hl, and + djnz delay_init0 ; ...right shift de by 4. + inc e ; fix up for value truncation + ld a,e ; put in a +#else + ld b,BF_SYSGET ; HBIOS func=get sys info + ld c,BF_SYSGET_CPUINFO ; HBIOS subfunc=get cpu info + rst 08 ; call HBIOS, rst 08 not yet installed + ld a,l ; put speed in mhz in accum +#endif + 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 +; +; 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 +; +; 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 +; +; Add hl,a +; +; A register is destroyed! +; +addhla: + add a,l + ld l,a + ret nc + inc h + 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 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 +; ;======================================================================= ; Console character I/O helper routines (registers preserved) ;======================================================================= @@ -1057,7 +1548,7 @@ cin: ; Input character from console via hbios ld c,CIO_CONSOLE ; console unit to c ld b,BF_CIOIN ; HBIOS func: input char - rst 08 ; HBIOS reads charactdr + rst 08 ; HBIOS reads character ld a,e ; move character to A for return ; ; Restore registers (AF is output) @@ -1180,13 +1671,13 @@ prtall1: ld hl,str_disk ; prefix string call pstr ; display it ld a,c ; index - call PRTDECB ; print it + call prtdecb ; print it ld hl,str_on ; separator string call pstr push bc ; save loop control ld b,BF_DIODEVICE ; HBIOS func: report device info rst 08 ; call HBIOS - call prtdrv ; print it + call prtdrv ; print it pop bc ; restore loop control inc c ; bump index djnz prtall1 ; loop as needed @@ -1207,7 +1698,7 @@ prtdrv: and $0F ; isolate device bits add a,a ; multiple by two for word table ld hl,devtbl ; point to start of table - call ADDHLA ; add A to HL for table entry + call addhla ; add A to HL for table entry ld a,(hl) ; deref HL for string adr inc hl ; ... ld h,(hl) ; ... @@ -1216,7 +1707,7 @@ prtdrv: pop hl ; recover HL pop de ; recover DE ld a,e ; device number - call PRTDECB ; print it + call prtdecb ; print it ld a,':' ; suffix call cout ; print it ret @@ -1279,7 +1770,7 @@ prtdrv: ld hl,str_disk ; prefix string call pstr ; display it ld a,b ; index - call PRTDECB ; print it + call prtdecb ; print it ld a,' ' ; formatting call cout ; do it ld a,'=' ; formatting @@ -1319,7 +1810,7 @@ prtdrv2: ; print device pop bc ; recover unit call pstr ; print device name ld a,b ; unit to a - call PRTDECB ; print it + call prtdecb ; print it ld a,':' ; device name suffix call cout ; print it ret ; done @@ -1341,6 +1832,7 @@ devunk .db "UNK",0 err_invcmd: ld hl,str_err_invcmd jr err +; err_nodisk: ld hl,str_err_nodisk jr err @@ -1349,6 +1841,10 @@ err_noslice: ld hl,str_err_noslice jr err ; +err_nocon: + ld hl,str_err_nocon + jr err +; err_diskio: ld hl,str_err_diskio jr err @@ -1377,6 +1873,7 @@ str_err_prefix .db bel,"\r\n\r\n*** ",0 str_err_invcmd .db "Invalid command",0 str_err_nodisk .db "Disk unit not available",0 str_err_noslice .db "Disk unit does not support slices",0 +str_err_nocon .db "Invalid character unit specification",0 str_err_diskio .db "Disk I/O failure",0 str_err_sig .db "No system image on disk",0 str_err_api .db "Unexpected hardware BIOS API failure",0 @@ -1386,10 +1883,12 @@ str_err_api .db "Unexpected hardware BIOS API failure",0 ;======================================================================= ; #define USEDELAY -#include "util.asm" +; #include "util.asm" ; #if (DSKYENABLE) #define DSKY_KBD +VDELAY .equ vdelay +DLY2 .equ dly2 #include "dsky.asm" #endif ; @@ -1408,12 +1907,14 @@ acmd_to .dw BOOT_TIMEOUT ; auto cmd timeout ;======================================================================= ; str_banner .db PLATFORM_NAME," Boot Loader",0 -;str_prompt .db "Boot [(H)elp]: ",0 +str_autoboot .db "AutoBoot: ",0 str_prompt .db "Boot [H=Help]: ",0 str_bs .db bs,' ',bs,0 str_reboot .db "\r\n\r\nRestarting System...",0 +str_newcon .db "\r\n\r\n Console on Unit #",0 +str_chspeed .db "\r\n\r\n Change speed now. Press a key to resume.",0 str_applst .db "\r\n\r\nROM Applications:",0 -str_devlst .db "\r\n\r\nDevices:",0 +str_devlst .db "\r\n\r\nDisk Devices:",0 str_invcmd .db "\r\n\r\n*** Invalid Command ***",bel,0 str_load .db "\r\n\r\nLoading ",0 str_disk .db "\r\n Disk Unit ",0 @@ -1425,12 +1926,18 @@ str_binfo2 .db $22," [0x",0 str_binfo3 .db "-0x",0 str_binfo4 .db ", entry @ 0x",0 str_binfo5 .db "]",0 +str_ldsec .db ", Sector 0x",0 +str_diaglvl .db "\r\n\r\nHBIOS Diagnostic Level: ",0 ; str_help .db "\r\n" - .db "\r\n L: List ROM Applications" - .db "\r\n D: Device Inventory" - .db "\r\n R: Reboot System" - .db "\r\n [.]: Boot Disk Unit/Slice" + .db "\r\n L - List ROM Applications" + .db "\r\n D - Disk Device Inventory" + .db "\r\n R - Reboot System" +#if (BIOS == BIOS_WBW) + .db "\r\n I [] - Set Console Interface/Baud code" + .db "\r\n V [] - View/Set HBIOS Diagnostic Verbosity" +#endif + .db "\r\n [.] - Boot Disk Unit/Slice" .db 0 ; #if (DSKYENABLE) @@ -1448,34 +1955,34 @@ msg_go .db $db,$9d,$00,$00,$00,$80,$80,$80 ; "go... " ; ; WBW UNA ; p1: Application name string adr word (+0) word (+0) -; p2: Console keyboard selection key byte (+2) byte (+2) -; p3: DSKY selection key byte (+3) byte (+3) -; p4: Application image bank byte (+4) word (+4) -; p5: Application image source address word (+5) word (+6) -; p6: Application image dest load address word (+7) word (+8) -; p7: Application image size word (+9) word (+10) -; p8: Application entry address word (+11) word (+12) +; p2: Console keyboard selection key byte (+2) byte (+2) +; p3: DSKY selection key byte (+3) byte (+3) +; p4: Application image bank byte (+4) word (+4) +; p5: Application image source address word (+5) word (+6) +; p6: Application image dest load address word (+7) word (+8) +; p7: Application image size word (+9) word (+10) +; p8: Application entry address word (+11) word (+12) ; #if (BIOS == BIOS_WBW) ra_name .equ 0 ra_conkey .equ 2 -ra_dskykey .equ 3 -ra_bnk .equ 4 -ra_src .equ 5 -ra_dest .equ 7 -ra_siz .equ 9 -ra_ent .equ 11 +ra_dskykey .equ 3 +ra_bnk .equ 4 +ra_src .equ 5 +ra_dest .equ 7 +ra_siz .equ 9 +ra_ent .equ 11 #endif ; #if (BIOS == BIOS_UNA) ra_name .equ 0 ra_conkey .equ 2 -ra_dskykey .equ 3 -ra_bnk .equ 4 -ra_src .equ 6 -ra_dest .equ 8 -ra_siz .equ 10 -ra_ent .equ 12 +ra_dskykey .equ 3 +ra_bnk .equ 4 +ra_src .equ 6 +ra_dest .equ 8 +ra_siz .equ 10 +ra_ent .equ 12 #endif ; #define ra_ent(p1,p2,p3,p4,p5,p6,p7,p8) \ @@ -1516,35 +2023,35 @@ ra_ent .equ 12 ; ra_tbl: ; -; Name Key Dsky Bank Src Dest Size Entry +; Name Key Dsky Bank Src Dest Size Entry ; --------- ------- ----- -------- ----- ------- ------- ---------- -ra_ent(str_mon, 'M', KY_CL, BID_IMG0, $1000, MON_LOC, MON_SIZ, MON_SERIAL) +ra_ent(str_mon, 'M', KY_CL, BID_IMG0, $1000, MON_LOC, MON_SIZ, MON_SERIAL) ra_entsiz .equ $ - ra_tbl -ra_ent(str_cpm22, 'C', KY_BK, BID_IMG0, $2000, CPM_LOC, CPM_SIZ, CPM_ENT) -ra_ent(str_zsys, 'Z', KY_FW, BID_IMG0, $5000, CPM_LOC, CPM_SIZ, CPM_ENT) +ra_ent(str_cpm22, 'C', KY_BK, BID_IMG0, $2000, CPM_LOC, CPM_SIZ, CPM_ENT) +ra_ent(str_zsys, 'Z', KY_FW, BID_IMG0, $5000, CPM_LOC, CPM_SIZ, CPM_ENT) #if (BIOS == BIOS_WBW) -ra_ent(str_fth, 'F', KY_EX, BID_IMG1, $0000, FTH_LOC, FTH_SIZ, FTH_LOC) -ra_ent(str_bas, 'B', KY_DE, BID_IMG1, $1700, BAS_LOC, BAS_SIZ, BAS_LOC) -ra_ent(str_tbas, 'T', KY_EN, BID_IMG1, $3700, TBC_LOC, TBC_SIZ, TBC_LOC) -ra_ent(str_play, 'P', $FF, BID_IMG1, $4000, GAM_LOC, GAM_SIZ, GAM_LOC) -ra_ent(str_user, 'U', $FF, BID_IMG1, $7000, USR_LOC, USR_SIZ, USR_LOC) +ra_ent(str_fth, 'F', KY_EX, BID_IMG1, $0000, FTH_LOC, FTH_SIZ, FTH_LOC) +ra_ent(str_bas, 'B', KY_DE, BID_IMG1, $1700, BAS_LOC, BAS_SIZ, BAS_LOC) +ra_ent(str_tbas, 'T', KY_EN, BID_IMG1, $3700, TBC_LOC, TBC_SIZ, TBC_LOC) +ra_ent(str_play, 'P', $FF, BID_IMG1, $4000, GAM_LOC, GAM_SIZ, GAM_LOC) +ra_ent(str_user, 'U', $FF, BID_IMG1, $7000, USR_LOC, USR_SIZ, USR_LOC) #endif #if (DSKYENABLE) ra_ent(str_dsky, 'Y'+$80, KY_GO, bid_cur, $1000, MON_LOC, MON_SIZ, MON_DSKY) #endif -ra_ent(str_egg, 'E'+$80, $FF , bid_cur, $0E00, EGG_LOC, EGG_SIZ, EGG_LOC) +ra_ent(str_egg, 'E'+$80, $FF , bid_cur, $0E00, EGG_LOC, EGG_SIZ, EGG_LOC) .dw 0 ; table terminator ; ra_tbl_app: ; -; Name Key Dsky Bank Src Dest Size Entry +; Name Key Dsky Bank Src Dest Size Entry ; --------- ------- ----- -------- ----- ------- ------- ---------- -ra_ent(str_mon, 'M', KY_CL, bid_cur, $1000, MON_LOC, MON_SIZ, MON_SERIAL) -ra_ent(str_zsys, 'Z', KY_FW, bid_cur, $2000, CPM_LOC, CPM_SIZ, CPM_ENT) +ra_ent(str_mon, 'M', KY_CL, bid_cur, $1000, MON_LOC, MON_SIZ, MON_SERIAL) +ra_ent(str_zsys, 'Z', KY_FW, bid_cur, $2000, CPM_LOC, CPM_SIZ, CPM_ENT) #if (DSKYENABLE) ra_ent(str_dsky, 'Y'+$80, KY_GO, bid_cur, $1000, MON_LOC, MON_SIZ, MON_DSKY) #endif -ra_ent(str_egg, 'E'+$80, $FF , bid_cur, $0E00, EGG_LOC, EGG_SIZ, EGG_LOC) +ra_ent(str_egg, 'E'+$80, $FF , bid_cur, $0E00, EGG_LOC, EGG_SIZ, EGG_LOC) .dw 0 ; table terminator ; str_mon .db "Monitor",0 @@ -1557,6 +2064,8 @@ str_tbas .db "Tasty BASIC",0 str_play .db "Play a Game",0 str_user .db "User App",0 str_egg .db "",0 +newcon .db 0 +newspeed .db 0 ; ;======================================================================= ; Pad remainder of ROM Loader @@ -1581,9 +2090,13 @@ bid_ldr .ds 1 ; bank at startup #endif #if (BIOS == BIOS_UNA) bid_ldr .ds 2 ; bank at startup -loadlba .ds 4 ; lba for load, dword #endif ; +lba .ds 4 ; lba for load, dword +dma .ds 2 ; address for load +sps .ds 2 ; sectors per slice +mediaid .ds 1 ; media id +; ra_tbl_loc .ds 2 ; points to active ra_tbl bootunit .ds 1 ; boot disk unit bootslice .ds 1 ; boot disk slice @@ -1615,5 +2128,11 @@ bb_biloc .ds 2 ; loc to patch boot drive info bb_cpmloc .ds 2 ; final ram dest for cpm/cbios bb_cpmend .ds 2 ; end address for load bb_cpment .ds 2 ; CP/M entry point (cbios boot) +; +; +; Master Boot Record sector is read into area below. +; +bl_mbrsec .equ $ + .ds 512 ; .end diff --git a/Source/HBIOS/sd.asm b/Source/HBIOS/sd.asm index b0b2e379..c3707e69 100644 --- a/Source/HBIOS/sd.asm +++ b/Source/HBIOS/sd.asm @@ -41,7 +41,7 @@ ; THE CLOCK IS LOW. THE DATA IS CAPTURED ON THE CLOCK'S LOW-TO-HIGH ; TRANSITION AND PROPAGATED ON HIGH-TO-LOW CLOCK TRANSITION. ; -; NOTE: THE CSIO IMPLEMENTATION (INCLUDE MK4) USES SPI MODE 4 +; NOTE: THE CSIO IMPLEMENTATION (INCLUDE MK4) USES SPI MODE 3 ; (CPOL=1, CPHA=1) BECAUSE THAT IS THE WAY THAT THE Z180 CSIO ; INTERFACE WORKS. ALL OF THE CLOCK TRANSITIONS LISTED ABOVE ; ARE REVERSED FOR CSIO. @@ -104,7 +104,7 @@ ; IS FLOATING IT IS IMPOSSIBLE TO DETERMINE IF THE BYTE RECEIVED IS A FILL ; BYTE OR NOT. BASED ON WHAT I HAVE READ, THERE WILL ALWAYS BE AT LEAST ; ONE FILL BYTE PRIOR TO THE ACTUAL RESULT. ADDITIONALLY, THE SD CARD WILL -; START DRIVING MISO SOMETIME WITHING THAT FIRST FILL BYTE. SO, WE NOW +; START DRIVING MISO SOMETIME WITHIN THAT FIRST FILL BYTE. SO, WE NOW ; JUST DISCARD THE FIRST BYTE RECEIVED AFTER A COMMAND IS SENT WITH THE ; ASSUMPTION THAT IT MUST BE A FILL BYTE AND IS NOT RELIABLE DUE TO FLOATING ; MISO. @@ -125,6 +125,7 @@ SD_CS0 .EQU %00000100 ; RTC:2 IS SELECT SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK SD_DI .EQU %00000001 ; RTC:0 IS DATA IN (CARD <- CPU) SD_DO .EQU %10000000 ; RTC:7 IS DATA OUT (CARD -> CPU) +SD_IOBASE .EQU SD_OPRREG ; IOBASE ; RTCDEF .SET SD_OPRDEF ; SET DEFAULT IN HBIOS MAINLINE #ENDIF @@ -139,6 +140,7 @@ SD_CS0 .EQU %00000100 ; RTC:2 IS SELECT SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK SD_DI .EQU %00000001 ; RTC:0 IS DATA IN (CARD <- CPU) SD_DO .EQU %01000000 ; RTC:6 IS DATA OUT (CARD -> CPU) +SD_IOBASE .EQU SD_OPRREG ; IOBASE ; RTCDEF .SET SD_OPRDEF ; SET DEFAULT IN HBIOS MAINLINE #ENDIF @@ -151,6 +153,7 @@ SD_OPRMSK .EQU %00000100 ; MASK FOR BITS WE OWN IN RTC LATCH PORT SD_CS0 .EQU %00000100 ; RTC:2 IS SELECT SD_CNTR .EQU Z180_CNTR SD_TRDR .EQU Z180_TRDR +SD_IOBASE .EQU SD_OPRREG ; IOBASE ; RTCDEF .SET SD_OPRDEF ; SET DEFAULT IN HBIOS MAINLINE #ENDIF @@ -168,6 +171,7 @@ SD_CS0 .EQU %00010000 ; PPIC:4 IS SELECT SD_CLK .EQU %00000010 ; PPIC:1 IS CLOCK SD_DI .EQU %00000001 ; PPIC:0 IS DATA IN (CARD <- CPU) SD_DO .EQU %10000000 ; PPIB:7 IS DATA OUT (CARD -> CPU) +SD_IOBASE .EQU SD_PPIBASE ; IOBASE #ENDIF ; #IF (SDMODE == SDMODE_UART) @@ -180,6 +184,7 @@ SD_CS0 .EQU %00001000 ; UART MCR:3 IS SELECT SD_CLK .EQU %00000100 ; UART MCR:2 IS CLOCK SD_DI .EQU %00000001 ; UART MCR:0 IS DATA IN (CARD <- CPU) SD_DO .EQU %00100000 ; UART MSR:5 IS DATA OUT (CARD -> CPU) +SD_IOBASE .EQU UARTIOB ; IOBASE #ENDIF ; #IF (SDMODE == SDMODE_DSD) ; DUAL SD @@ -193,6 +198,7 @@ SD_CS0 .EQU %00000100 ; RTC:2 IS SELECT SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK SD_DI .EQU %00000001 ; RTC:6 IS DATA IN (CARD <- CPU) SD_DO .EQU %00000001 ; RTC:0 IS DATA OUT (CARD -> CPU) +SD_IOBASE .EQU SD_OPRREG ; IOBASE #ENDIF ; #IF (SDMODE == SDMODE_MK4) ; MARK IV (CSIO STYLE INTERFACE) @@ -202,6 +208,7 @@ SD_OPRDEF .EQU %00000000 ; QUIESCENT STATE SD_CS0 .EQU %00000100 ; SELECT ACTIVE SD_CNTR .EQU Z180_CNTR SD_TRDR .EQU Z180_TRDR +SD_IOBASE .EQU SD_OPRREG ; IOBASE #ENDIF ; #IF (SDMODE == SDMODE_SC) ; SC @@ -213,6 +220,7 @@ SD_CS0 .EQU %00000100 ; RTC:2 IS SELECT FOR PRIMARY SPI CARD SD_CS1 .EQU %00001000 ; RTC:3 IS SELECT FOR SECONDARY SPI CARD SD_CNTR .EQU Z180_CNTR SD_TRDR .EQU Z180_TRDR +SD_IOBASE .EQU SD_OPRREG ; IOBASE ; RTCDEF .SET SD_OPRDEF ; SET DEFAULT IN HBIOS MAINLINE #ENDIF @@ -236,7 +244,7 @@ SD_CD1 .EQU %00000100 ; IN:SD_OPREG:2 = CD2, IN=0 Card detect switch SD_CSX .EQU %00001000 ; IN/OUT:SD_OPREG:3 = CS0, PMOD SPI CS SD_CS0 .EQU %00010000 ; IN/OUT:SD_OPREG:4 = CS1, SDCARD1 CS, IN=1 Card present SD_CS1 .EQU %00100000 ; IN/OUT:SD_OPREG:5 = CS2, SDCARD2 CS, IN=1 Card present - +SD_IOBASE .EQU SD_BASE ; IOBASE #ENDIF ; ; SD CARD COMMANDS @@ -672,7 +680,10 @@ SD_FNTBL: SD_VERIFY: SD_FORMAT: SD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL SYSCHK ; INVALID SUB-FUNCTION + LD A,ERR_NOTIMPL + OR A + RET ; ; ; @@ -697,10 +708,26 @@ SD_IO: LD (SD_BLKCNT),A ; ... AND SAVE IT OR A ; SET FLAGS RET Z ; ZERO SECTOR I/O, RETURN W/ E=0 & A=0 +; +#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) + ; CONSIDER CAPTURING CURRENT CNTR VALUE HERE AND USE IT + ; IN SD_CSIO_DEF + + ; SET CSIO FOR HIGH SPEED OPERATION + CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING + CALL DLY32 ; WAIT A BIT MORE FOR FINAL BIT + XOR A ; ZERO MEANS MAX SPEED + OUT0 (SD_CNTR),A ; NOW SET CSIO PORT + ; HOOK RETURN TO RESTORE CSIO TO DEFAULT SPEED + LD HL,SD_CSIO_DEF ; ROUTE RETURN + PUSH HL ; ... THRU CSIO RESTORE +#ENDIF +; #IF (SDTRACE == 1) LD HL,SD_PRTERR ; SET UP SD_PRTERR PUSH HL ; ... TO FILTER ALL EXITS #ENDIF +; CALL SD_SELUNIT ; HARDWARE SELECTION OF TARGET UNIT RET NZ ; ABORT ON ERROR LD A,(SD_CMDVAL) ; GET COMMAND VALUE @@ -737,7 +764,10 @@ SD_IO3: LD E,C ; SECTOR READ COUNT TO E LD HL,(SD_DSKBUF) ; CURRENT DMA TO HL OR A ; SET FLAGS BASED ON RETURN CODE - RET ; AND RETURN, A HAS RETURN CODE + RET Z ; RETURN IF SUCCESS + LD A,ERR_IO ; SIGNAL IO ERROR + OR A ; SET FLAGS + RET ; AND DONE ; ; ; @@ -765,6 +795,8 @@ SD_DEVICE: LD D,DIODEV_SD ; D := DEVICE TYPE LD E,(IY+SD_DEV) ; E := PHYSICAL DEVICE NUMBER LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD + LD H,SDMODE ; H := MODE + LD L,(SD_IOBASE) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -802,6 +834,8 @@ SD_MEDIA2: LD E,MID_HD ; ASSUME WE ARE OK RET Z ; RETURN IF GOOD INIT LD E,MID_NONE ; SIGNAL NO MEDIA + LD A,ERR_NOMEDIA ; NO MEDIA ERROR + OR A ; SET FLAGS RET ; AND RETURN ; ; @@ -853,6 +887,10 @@ SD_INITCARD: ; CALL SD_CHKCD ; CHECK CARD DETECT JP Z,SD_NOMEDIA ; Z=NO MEDIA, HANDLE IF SO +; +#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) + CALL SD_CSIO_DEF ; ENSURE CSIO AT DEFAULT SPEED +#ENDIF ; ; WAKE UP THE CARD, KEEP DIN HI (ASSERTED) AND /CS HI (DEASSERTED) LD B,$10 ; MIN 74 CLOCKS REQUIRED, WE USE 128 ($10 * 8) @@ -866,7 +904,7 @@ SD_INITCARD1: ; MAKE SURE WE FINISH SENDING #IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) CALL SD_WAITTX ; WAIT FOR TE TO CLEAR - CALL DLY4 ; WAIT A BIT MORE FOR FINAL BIT + CALL DLY32 ; WAIT A BIT MORE FOR FINAL BIT #ENDIF ; ; PUT CARD IN IDLE STATE @@ -898,9 +936,6 @@ SD_INITCARD3: CALL VDELAY ; CPU SPEED NORMALIZED DELAY ; SEND APP CMD INTRODUCER CALL SD_EXECACMD ; SEND APP COMMAND INTRODUCER -;#IF (SDMODE == SDMODE_MT) -; CALL NZ,SD_EXECACMD ; retry any fail -;#ENDIF CP SD_STCMDERR ; COMMAND ERROR? JR Z,SD_INITCARD3A ; IF SO, TRY MMC CARD INIT OR A ; SET FLAGS @@ -911,7 +946,11 @@ SD_INITCARD3: LD A,$40 ; P0 = $40 INDICATES WE SUPPORT V2 CARDS LD (SD_CMDP0),A ; SET COMMAND PARM 0 CALL SD_EXECCMDND ; EXEC COMMAND W/ NO DATA RETURNED - RET NZ ; ABORT ON ERROR + ;RET NZ ; ABORT ON ERROR + CP SD_STCMDERR ; COMMAND ERROR? + JR Z,SD_INITCARD3A ; IF SO, TRY MMC CARD INIT + OR A ; SET FLAGS + RET NZ ; ABORT IF ANY OTHER ERROR ; CHECK FOR IDLE, EXIT LOOP IF IDLE CLEARED LD A,(SD_RC) ; GET CARD RESULT CODE OR A ; SET FLAGS @@ -1021,13 +1060,16 @@ SD_INITCARD5: CALL SD_EXECCMDND ; EXEC COMMAND W/ NO DATA RET NZ ; ABORT ON ERROR -#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) - ; PER SPEC, THE CARD SHOULD NOW BE ABLE TO HANDLE FULL SPEED OPERATION - ; SO, FOR CSIO OPERATION, WE SET CSIO TO MAXIMUM SPEED - CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - XOR A ; ZERO MEANS MAX SPEED - OUT (Z180_CNTR),A ; NOW SET CSIO PORT -#ENDIF +; HIGH SPEED CSIO OPERATION IS NOW SET AT THE START OF SD_IO +; +;#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) +; ; PER SPEC, THE CARD SHOULD NOW BE ABLE TO HANDLE FULL SPEED OPERATION +; ; SO, FOR CSIO OPERATION, WE SET CSIO TO MAXIMUM SPEED +; CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING +; CALL DLY32 ; WAIT A BIT MORE FOR FINAL BIT +; XOR A ; ZERO MEANS MAX SPEED +; OUT0 (SD_CNTR),A ; NOW SET CSIO PORT +;#ENDIF ; ; ISSUE SEND_CSD (TO DERIVE CARD CAPACITY) LD A,SD_CMD_SEND_CSD ; SEND_CSD @@ -1053,10 +1095,14 @@ SD_INITCARD5: ; GET SIZE OF DEVICE IN BLOCKS LD A,(IY+SD_TYPE) ; GET CARD TYPE OR A ; SET FLAGS - CALL Z,PANIC ; PANIC IF CARD TYPE UNKNOWN + JR Z,SD_INITCARD5A ; HANDLE CARD TYPE UNKNOWN CP SD_TYPESDHC ; COMPARE TO SDHC (V2) JP NC,SD_INITCARD8 ; HANDLE SDHC (V2) OR BETTER JR SD_INITCARD6 ; HANDLE MMC OR SDSC +; +SD_INITCARD5A: + CALL SYSCHK + JP SD_NOMEDIA ; ; CAPACITY CALCULATION FOR MMC OR SDSC (V1) CARDS: ; BYTES = (C_SIZE + 1) * 2^(2+C_SIZE_MULT+READ_BL_LEN) = (C_SIZE+1) << (2+C_SIZE_MULT+READ_BL_LEN) @@ -1164,6 +1210,9 @@ SD_SECTIO: CP SD_CMD_WRITE_BLOCK ; WRITE_BLOCK? JR Z,SD_SECTIO2 ; HANDLE WRITE CALL PANIC ; PANIC ON ANYTHING ELSE + LD A,ERR_INTERNAL + OR A + RET SD_SECTIO1: ; GET SECTOR DATA CALL SD_GETDATA ; GET THE BLOCK @@ -1271,6 +1320,12 @@ SD_INITCMD1: INC HL ; POINT TO NEXT BYTE LD (HL),A ; CLEAR IT DJNZ SD_INITCMD1 ; LOOP TILL DONE + ; CRC POSITION SHOULD BE COMPLETELY IGNORED BECAUSE WE DON'T + ; ENABLE IT AND WE ARE IN SPI MODE. HOWEVER, AT LEAST ONE SD + ; CARD IS KNOWN TO FAIL ANY COMMAND WHERE THE CRC POSITION + ; IS NOT $FF! SO, BELOW WE STUFF THE CRC POSITION WITH $FF. + DEC A ; $FF TO ACCUM + LD (SD_CMDCRC),A ; PUT $FF IN CRC POSITION RET ; ; EXECUTE APP COMMAND @@ -1334,7 +1389,19 @@ SD_EXECCMD1: ; THE FIRST FILL BYTE IS DISCARDED! THIS HACK IS REQUIRED BY ; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE ; COMMENTS AT TOP OF THIS FILE. - CALL SD_GET ; GET A BYTE AND DISCARD IT +; + ;CALL SD_GET ; GET A BYTE AND DISCARD IT +; + ; THE Z180 -K REVISION CSIO DOES NOT KEEP MOSI HIGH WHEN + ; RECEIVING VIA MISO. INSTEAD MOSI IS LEFT AT WHICHEVER LOGIC + ; LEVEL IT WAS LAST SET TO. THIS CAUSES SOME SD CARDS A PROBLEM + ; BECAUSE THEY EXPECT MOSI TO BE CONSISTENTLY HIGH WHEN IDLE. + ; BY USING A PUT INSTEAD OF A GET, WE CAN FORCE MOSI TO BE + ; LEFT AT THE PROPER LOGIC LEVEL. THE SD CARD DOES NOT CARE + ; IF A PUT OR A GET IS USED TO IGNORE THE BYTE BECAUSE THE + ; CLOCK RUNS IN EITHER CASE. + LD A,$FF ; KEEP MOSI HI + CALL SD_PUT ; SEND 8 CLOCKS #ENDIF ; ; GET RESULT @@ -1660,6 +1727,11 @@ SD_SELECT2: #ENDIF LD (SD_OPRVAL),A OUT (SD_OPRREG),A +;; +;#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) +; CALL DLY32 ; DELAY FOR FINAL BIT +;#ENDIF +; RET ; ; DESELECT CARD @@ -1673,12 +1745,10 @@ SD_DESELECT: ; FINISH SENDING AFTER TE IS CLEARED. THE DELAY BELOW WILL ; DO THIS FOR THE SLOWEST POSSIBLE SEND RATE WHICH IS ; CLK / 1320, SO DELAY AT LEAST 1320 T-STATES - ;CALL DLY64 ; DELAY FOR FINAL BIT ; - ; IN PRACTICE, IT LOOKS LIKE THIS WORST CASE SCENARIO NEVER - ; OCCURS. FOR NOW, USE A SMALL DELAY WHICH SEEMS TO BE MORE - ; THAN ADEQUATE BASED ON LOGIC ANALYZER TRACES. - CALL DLY4 ; DELAY FOR FINAL BIT + ; IN PRACTICE, A SMALLER DELAY IS FINE BASED ON LOGIC ANALYZER + ; TRACES. + CALL DLY32 ; DELAY FOR FINAL BIT #ENDIF ; LD A,(SD_OPRVAL) @@ -1703,19 +1773,19 @@ SD_DESELECT: ; ; CSIO WAIT FOR TRANSMIT READY (TX REGSITER EMPTY) ; -SD_WAITTX: ; WAIT FOR TX EMPTY +SD_WAITTX: IN0 A,(SD_CNTR) ; GET CSIO STATUS BIT 4,A ; TX EMPTY? - JR NZ,SD_WAITTX - RET + JR NZ,SD_WAITTX ; LOOP WHILE BUSY + RET ; DONE ; ; CSIO WAIT FOR RECEIVER READY (BYTE AVAILABLE) ; SD_WAITRX: IN0 A,(SD_CNTR) ; WAIT FOR RECEIVER TO FINISH - BIT 5,A - JR NZ,SD_WAITRX - RET + BIT 5,A ; RX EMPTY? + JR NZ,SD_WAITRX ; LOOP WHILE BUSY + RET ; DONE ; #ENDIF ; @@ -1767,11 +1837,11 @@ SD_GET: #ELSE #IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - IN0 A,(Z180_CNTR) ; GET CSIO STATUS + IN0 A,(SD_CNTR) ; GET CSIO STATUS SET 5,A ; START RECEIVER - OUT0 (Z180_CNTR),A + OUT0 (SD_CNTR),A CALL SD_WAITRX - IN0 A,(Z180_TRDR) ; GET RECEIVED BYTE + IN0 A,(SD_TRDR) ; GET RECEIVED BYTE CALL MIRROR ; MSB<-->LSB MIRROR BITS LD A,C ; KEEP RESULT #ELSE @@ -1808,6 +1878,23 @@ SD_GET1: #ENDIF RET ; +; SET CSIO TO DEFAULT SPEED +; +#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) +; +SD_CSIO_DEF: + ; SET CSIO FOR DEFAULT OPERATION + PUSH AF ; PRESERVE AF + CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING + CALL DLY32 ; WAIT A BIT MORE FOR FINAL BIT + LD A,Z180_CNTR_DEF ; DIV 1280, 14KHZ @ 18MHZ CLK + OUT0 (SD_CNTR),A ; DO IT + POP AF ; RESTORE AF + RET +; +#ENDIF +; +; ;============================================================================= ; ERROR HANDLING AND DIAGNOSTICS ;============================================================================= diff --git a/Source/HBIOS/simrtc.asm b/Source/HBIOS/simrtc.asm index 8be545c3..f144d1aa 100644 --- a/Source/HBIOS/simrtc.asm +++ b/Source/HBIOS/simrtc.asm @@ -49,7 +49,16 @@ SIMRTC_DISPATCH: JP Z,SIMRTC_GETBLK ; GET NVRAM DATA BLOCK VALUES DEC A JP Z,SIMRTC_SETBLK ; SET NVRAM DATA BLOCK VALUES - CALL PANIC + DEC A + JP Z,SIMRTC_GETALM ; GET ALARM + DEC A + JP Z,SIMRTC_SETALM ; SET ALARM + DEC A + JP Z,SIMRTC_DEVICE ; REPORT RTC DEVICE INFO + CALL SYSCHK + LD A,ERR_NOFUNC + OR A + RET ; ; NVRAM FUNCTIONS ARE NOT AVAILABLE IN SIMULATOR ; @@ -57,7 +66,12 @@ SIMRTC_GETBYT: SIMRTC_SETBYT: SIMRTC_GETBLK: SIMRTC_SETBLK: - CALL PANIC +SIMRTC_GETALM: +SIMRTC_SETALM: + CALL SYSCHK + LD A,ERR_NOTIMPL + OR A + RET ; ; RTC GET TIME ; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR @@ -121,6 +135,16 @@ SIMRTC_SETTIM: XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; +; REPORT RTC DEVICE INFO +; +SIMRTC_DEVICE: + LD D,RTCDEV_SIMH ; D := DEVICE TYPE + LD E,0 ; E := PHYSICAL DEVICE NUMBER + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,SIMRTC_IO ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; ; WORKING VARIABLES ; SIMRTC_BUF: ; ALL IN BCD!!! diff --git a/Source/HBIOS/sio.asm b/Source/HBIOS/sio.asm index 31000849..5a013853 100644 --- a/Source/HBIOS/sio.asm +++ b/Source/HBIOS/sio.asm @@ -30,7 +30,7 @@ SIO_WR1VAL .EQU $00 ; WR1 VALUE FOR NO INTS SIO_WR1VAL .EQU $18 ; WR1 VALUE FOR INT ON RECEIVED CHARS #ENDIF ; -#IF (INTMODE == 2) +#IF ((INTMODE == 2) | (INTMODE == 3)) ; SIO0_IVT .EQU IVT(INT_SIO0) SIO1_IVT .EQU IVT(INT_SIO1) @@ -39,6 +39,13 @@ SIO1_VEC .EQU VEC(INT_SIO1) ; #ENDIF ; +#IF (SIO0MODE == SIOMODE_STD) +SIO0A_CMD .EQU SIO0BASE + $01 +SIO0A_DAT .EQU SIO0BASE + $00 +SIO0B_CMD .EQU SIO0BASE + $03 +SIO0B_DAT .EQU SIO0BASE + $02 +#ENDIF +; #IF (SIO0MODE == SIOMODE_RC) SIO0A_CMD .EQU SIO0BASE + $00 SIO0A_DAT .EQU SIO0BASE + $01 @@ -60,42 +67,35 @@ SIO0B_CMD .EQU SIO0BASE + $07 SIO0B_DAT .EQU SIO0BASE + $05 #ENDIF ; -#IF (SIO0MODE == SIOMODE_EZZ80) -SIO0A_CMD .EQU SIO0BASE + $01 -SIO0A_DAT .EQU SIO0BASE + $00 -SIO0B_CMD .EQU SIO0BASE + $03 -SIO0B_DAT .EQU SIO0BASE + $02 -#ENDIF -; #IF (SIOCNT >= 2) ; -#IF (SIO1MODE == SIOMODE_RC) + #IF (SIO1MODE == SIOMODE_STD) +SIO1A_CMD .EQU SIO1BASE + $01 +SIO1A_DAT .EQU SIO1BASE + $00 +SIO1B_CMD .EQU SIO1BASE + $03 +SIO1B_DAT .EQU SIO1BASE + $02 + #ENDIF +; + #IF (SIO1MODE == SIOMODE_RC) SIO1A_CMD .EQU SIO1BASE + $00 SIO1A_DAT .EQU SIO1BASE + $01 SIO1B_CMD .EQU SIO1BASE + $02 SIO1B_DAT .EQU SIO1BASE + $03 -#ENDIF + #ENDIF ; -#IF (SIO1MODE == SIOMODE_SMB) + #IF (SIO1MODE == SIOMODE_SMB) SIO1A_CMD .EQU SIO1BASE + $02 SIO1A_DAT .EQU SIO1BASE + $00 SIO1B_CMD .EQU SIO1BASE + $03 SIO1B_DAT .EQU SIO1BASE + $01 -#ENDIF + #ENDIF ; -#IF (SIO1MODE == SIOMODE_ZP) + #IF (SIO1MODE == SIOMODE_ZP) SIO1A_CMD .EQU SIO1BASE + $06 SIO1A_DAT .EQU SIO1BASE + $04 SIO1B_CMD .EQU SIO1BASE + $07 SIO1B_DAT .EQU SIO1BASE + $05 -#ENDIF -; -#IF (SIO1MODE == SIOMODE_EZZ80) -SIO1A_CMD .EQU SIO1BASE + $01 -SIO1A_DAT .EQU SIO1BASE + $00 -SIO1B_CMD .EQU SIO1BASE + $03 -SIO1B_DAT .EQU SIO1BASE + $02 -#ENDIF + #ENDIF ; #ENDIF ; @@ -138,62 +138,24 @@ SIO_PREINIT2: OR A ; SET FLAGS JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES, ABORT ; -#IF (INTMODE == 1) + #IF (INTMODE == 1) ; ADD IM1 INT CALL LIST ENTRY LD HL,SIO_INT ; GET INT VECTOR CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST -#ENDIF + #ENDIF ; -#IF (INTMODE == 2) - ; SETUP IM2 VECTORS + #IF ((INTMODE == 2) | (INTMODE == 3)) + ; SETUP IM2/3 VECTORS LD HL,SIO_INT0 LD (SIO0_IVT),HL ; IVT INDEX ; -#IF (SIOCNT >= 2) + #IF (SIOCNT >= 2) LD HL,SIO_INT1 LD (SIO1_IVT),HL ; IVT INDEX -#ENDIF -; -#ENDIF + #ENDIF ; -#ENDIF -; -; FOR NOW, THIS IS SPECIFICALLY FOR A CTC TO DRIVE AN SIO -; AT 1:1 USING CTC CHANNELS A & B. IN OTHER WORDS, IT JUST -; PASSES THE INCOMING TRIGGER OUT AT 1:1. -; -#IF (SIOCNT >= 1) - #IF (SIO0CTCC >= 0) - LD A,%01010111 ; CTCC CONTROL WORD VALUE - ; |||||||+-- 1=CONTROL WORD FLAG - ; ||||||+--- 1=SOFTWARE RESET - ; |||||+---- 1=TIME CONSTANT FOLLOWS - ; ||||+----- 0=AUTO TRIGGER WHEN TIME CONST LOADED - ; |||+------ 1=RISING EDGE TRIGGER - ; ||+------- 0=PRESCALER OF 16 (NOT USED) - ; |+-------- 1=COUNTER MODE - ; +--------- 0=NO INTERRUPTS - OUT (CTCA + SIO0CTCC),A ; SETUP CTCC - LD A,1 ; CTC TIMER CONSTANT = 1 - OUT (CTCA + SIO0CTCC),A ; SETUP CTC TIMER CONSTANT #ENDIF -#ENDIF ; -#IF (SIOCNT >= 2) - #IF (SIO1CTCC >= 0) - LD A,%01010111 ; CTCC CONTROL WORD VALUE - ; |||||||+-- 1=CONTROL WORD FLAG - ; ||||||+--- 1=SOFTWARE RESET - ; |||||+---- 1=TIME CONSTANT FOLLOWS - ; ||||+----- 0=AUTO TRIGGER WHEN TIME CONST LOADED - ; |||+------ 1=RISING EDGE TRIGGER - ; ||+------- 0=PRESCALER OF 16 (NOT USED) - ; |+-------- 1=COUNTER MODE - ; +--------- 0=NO INTERRUPTS - OUT (CTCA + SIO1CTCC),A ; SETUP CTCC - LD A,1 ; CTC TIMER CONSTANT = 1 - OUT (CTCA + SIO1CTCC),A ; SETUP CTC TIMER CONSTANT - #ENDIF #ENDIF ; SIO_PREINIT3: @@ -258,12 +220,12 @@ SIO_INT: CALL NZ,SIO_INT0 ; CALL IF CARD EXISTS RET NZ ; DONE IF INT HANDLED ; -#IF (SIOCNT >= 2) + #IF (SIOCNT >= 2) ; CHECK/HANDLE SECOND CARD (SIO1) IF IT EXISTS LD A,(SIO1A_CFG + 1) ; GET SIO TYPE FOR FIRST CHANNEL OF SECOND SIO OR A ; SET FLAGS CALL NZ,SIO_INT1 ; CALL IF CARD EXISTS -#ENDIF + #ENDIF ; RET ; DONE ; @@ -277,7 +239,7 @@ SIO_INT0: LD IY,SIO0B_CFG ; POINT TO SIO0B CFG JR SIO_INTRCV ; TRY TO RECEIVE FROM IT AND RETURN ; -#IF (SIOCNT >= 2) + #IF (SIOCNT >= 2) ; SIO_INT1: ; INTERRUPT HANDLER FOR SECOND SIO (SIO1) @@ -287,7 +249,7 @@ SIO_INT1: LD IY,SIO1B_CFG ; POINT TO SIO1B CFG JR SIO_INTRCV ; TRY TO RECEIVE FROM IT AND RETURN ; -#ENDIF + #ENDIF ; ; HANDLE INT FOR A SPECIFIC CHANNEL ; BASED ON UNIT CFG POINTED TO BY IY @@ -538,72 +500,245 @@ SIO_INITDEV1: CALL PRTHEXWORD #ENDIF ; - LD A,E ; GET CONFIG LSB - AND $E0 ; CHECK FOR DTR, XON, PARITY=MARK/SPACE - JR NZ,SIO_INITFAIL ; IF ANY BIT SET, FAIL, NOT SUPPORTED + PUSH DE ; SAVE TARGET CONFIG +; + ; WE WANT TO DETERMINE A DIVISOR FOR THE SIO CLOCK + ; THAT RESULTS IN THE DESIRED BAUD RATE. + ; BAUD RATE = SIO CLK / DIVISOR, OR TO SOLVE FOR DIVISOR + ; DIVISOR = SIO CLK / BAUDRATE. + ; TAKE ADVANTAGE OF ENCODED BAUD RATES ALWAYS BEING A FACTOR OF 75. + ; SO, WE CAN USE (SIO OSC / 75) / (BAUDRATE / 75) +; + ; GET SERIAL CLOCK VALUE AND DIVIDE IT BY 75 + PUSH IY ; GET CONFIG TABLE ENTRY PTR + POP HL ; MOVE TO HL + LD A,9 ; OFFSET TO CLK VALUE + CALL ADDHLA ; HL IS NOW PTR TO 32 BIT CLK + CALL LD32 ; LOAD DE:HL W/ RAW CLK VAL + LD C,75 ; DIVIDE BY 75 LIKE BAUD RATE + CALL DIV32X8 ; HL NOW HAS (CLK / 75) +; +#IF (SIODEBUG) + PRTS(" CLK75=$") + CALL PRTHEX32 +#ENDIF +; + ; SCALE DOWN THE 32 BIT VALUE TO FIT IN 16 BITS KEEPING + ; TRACK OF THE NUMBER OF BITS SHIFTED OUT IN B + LD B,0 ; SHIFT COUNTER +SIO_INITDEV1A: + LD A,D ; TEST MSB + OR E ; ... FOR ZERO + JR Z,SIO_INITDEV1B ; IF SO, DONE + SRL D ; 32 BIT RIGHT SHIFT + RR E ; ... + RR H ; ... + RR L ; ... + INC B ; INCREMENT SHIFT COUNTER + JR SIO_INITDEV1A ; AND LOOP +SIO_INITDEV1B: +; +#IF (SIODEBUG) + PRTS(" CLK=$") + CALL PRTHEX32 +#ENDIF ; + POP DE ; RECOVER INCOMING TARGET CFG + PUSH DE ; RESAVE IT + PUSH HL ; SAVE CLK VALUE + PUSH BC ; SAVE BITS SHIFTED + + ; NOW DECODE THE BAUDRATE, BUT WE USE A CONSTANT OF 1 INSTEAD + ; OF THE NORMAL 75. THIS PRODUCES (BAUDRATE / 75). LD A,D ; GET CONFIG MSB AND $1F ; ISOLATE ENCODED BAUD RATE + LD L,A ; PUT IN L + LD H,0 ; H IS ALWAYS ZERO + LD DE,1 ; USE 1 FOR ENCODING CONSTANT + CALL DECODE ; DE:HL := BAUD RATE, ERRORS IGNORED ; #IF (SIODEBUG) - PRTS(" ENC=$") - CALL PRTHEXBYTE + PRTS(" BAUD75=$") + CALL PRTHEX32 #ENDIF -; - PUSH DE ; SAVE REQUESTED CONFIG - LD L,(IY+9) ; LOAD CLK FREQ - LD H,(IY+10) ; ... INTO DE:HL - LD E,(IY+11) ; ... " - LD D,(IY+12) ; ... " - LD C,75 ; BAUD RATE ENCODING CONSTANT - CALL ENCODE ; C = TEST BAUD RATE (ENCODED) = BAUDTST - POP DE ; GET REQ CONFIG BACK, D = BAUDREQ -; - ; BIT 4 (DIV 3) OF BAUDREQ AND BAUDTST MUST MATCH! - LD A,C ; A = BAUDTST - XOR D ; XOR WITH BAUDREQ - BIT 4,A ; DO BIT 4 VALS MATCH? - JR NZ,SIO_INITFAIL ; IF NOT, BAIL OUT -; - LD A,C ; BAUDTST TO A - AND $0F ; ISOLATE DIV 2 BAUD BITS - LD C,A ; C = BAUDTST ; - LD A,D ; MSB W/ BAUD RATE TO A - AND $0F ; ISOLATE DIV 2 BAUD BITS - LD L,A ; L = BAUDREQ -; -; PUSH AF ; *DEBUG* -; CALL NEWLINE ; *DEBUG* -; LD A,L ; *DEBUG* -; CALL PRTHEXBYTE ; *DEBUG* -; LD A,C ; *DEBUG* -; CALL PRTHEXBYTE ; *DEBUG* -; CALL NEWLINE ; *DEBUG* -; POP AF ; *DEBUG* -; - LD A,C ; A = BAUDTST - LD B,$04 ; SIO R4 VAL FOR DIV 1 - CP L ; BAUDTST = BAUDREQ? - JR Z,SIO_INITBROK ; IF MATCH, WE ARE DONE -; - SUB 4 ; DIVIDE BY 16 (NOW DIV 16 TOT) - JR C,SIO_INITFAIL ; FAIL IF UNDERFLOW - LD B,$44 ; SIO R4 VAL FOR DIV 16 - CP L ; BAUDTST = BAUDREQ? - JR Z,SIO_INITBROK ; IF MATCH, WE ARE DONE -; - SUB 1 ; DIVIDE BY 2 (NOW DIV 32 TOT) - JR C,SIO_INITFAIL ; FAIL IF UNDERFLOW - LD B,$84 ; SIO R4 VAL FOR DIV 32 - CP L ; BAUDTST = BAUDREQ? - JR Z,SIO_INITBROK ; IF MATCH, WE ARE DONE + ; SCALE DOWN CLK BY SAME AMOUNT AS BAUD RATE + POP BC ; RESTORE BITS TO SHIFT + LD A,B ; PUT IN ACCUM + OR A ; TEST FOR ZERO + JR Z,SIO_INITDEV1D ; IF ZERO, NO SHIFT, SKIP +SIO_INITDEV1C: + SRL D ; 32 BIT RIGHT SHIFT + RR E ; ... + RR H ; ... + RR L ; ... + DJNZ SIO_INITDEV1C ; LOOP UNTIL DONE SHIFTING +SIO_INITDEV1D: +; +#IF (SIODEBUG) + PRTS(" BAUD=$") + CALL PRTHEX32 +#ENDIF ; - SUB 1 ; DIVIDE BY 2 (NOW DIV 64 TOT) - JR C,SIO_INITFAIL ; FAIL IF UNDERFLOW - LD B,$C4 ; SIO R4 VAL FOR DIV 64 - CP L ; BAUDTST = BAUDREQ? - JR Z,SIO_INITBROK ; IF MATCH, WE ARE DONE + POP DE ; RECOVER CLOCK + EX DE,HL ; SWAP CLOCK & BAUD FOR DIV + ; *** HANDLE DIVIDE BY ZERO??? *** + CALL DIV16 ; BC := HL/DE == TARGET DIVISOR +; +#IF (SIODEBUG) + PRTS(" DIV=$") + CALL PRTHEXWORD +#ENDIF +; +#IF (CTCENABLE) +; + LD A,(IY+13) ; GET CTC CHANNEL + INC A ; $FF -> 0 + JR Z,SIO_ADJDONE ; NO CTC CHANNEL, BYPASS +; + ; HERE WE NEED TO ACCOUNT FOR A SPECIAL CASE OF THE CTC. + ; IF THE CTC TRIGGER RATE IS MORE THAN HALF OF THE CTC CLOCK, + ; THEN THE CTC WILL ONLY COUNT EVERY OTHER TRIGGER PULSE. + ; IN THIS SITUATION, WE NEED TO CUT THE DIVISOR IN HALF + ; TO ACCOUNT FOR THIS. + ; FOR NOW, I JUST TEST TO SEE IF THE CTC TRIGGER AND THE CTC + ; CLOCK ARE THE SAME. I DOUBT THERE IS ANY REALISTIC + ; SCENARIO WHERE THE TRIGGER IS GREATER THAN HALF THE + ; CLOCK BUT ALSO NOT EQUAL TO THE CLOCK. + ; I DON'T DEFINITELY KNOW THE CTC CLOCK FREQ, BUT ASSUME IT + ; IS THE SAME AS THE CPU CLOCK, WHICH IT SHOULD BE. + ; FINALLY, NOTE THAT I AM COMPARING AGAINST THE CPU SPEED + ; DECLARED IN THE BUILD CONFIG, NOT THE DYNAMICALLY MEASURED + ; CPU SPEED. THIS IS CORRECT BECAUSE WE ARE REALLY TRYING TO + ; TEST IF THE CPU CLOCK AND THE TRIGGER FREQ ARE THE *SAME*. + ; ONLY COMPARING THE HIGH WORD VALUES, THAT SHOULD BE ENOUGH. +; + LD A,$FF & (CPUOSC >> 24) ; HIGH BYTE OF CPU FREQ + CP (IY+12) ; CP TO HIGH BYTE OF TRG + JR NZ,SIO_ADJDONE ; IF NE, SKIP ADJUSTMENT + LD A,$FF & (CPUOSC >> 16) ; HIGH BYTE OF CPU FREQ + CP (IY+11) ; CP TO HIGH BYTE OF TRG + JR NZ,SIO_ADJDONE ; IF NE, SKIP ADJUSTMENT +; + SRL B ; RIGHT SHIFT HL + RR C ; ... TO DIVIDE BY 2 + JR NC,SIO_ADJDONE ; DONE IF NO CARRY +; + ; IF CARRY, RESULTANT DIVISOR IS UNWORKABLE + POP DE ; POP STACK + JR SIO_INITFAIL ; AND FAIL + + ; *** CHECK FOR CARRY??? *** +; + #IF (SIODEBUG) + PRTS(" DIV=$") + CALL PRTHEXWORD + #ENDIF +; +SIO_ADJDONE: +; +#ENDIF +; + ; NOW THAT WE HAVE THE TARGET BAUD RATE DIVISOR, WE WILL + ; ATTEMPT TO IMPLEMENT IT. THE SIO ITSELF CAN APPLY + ; A DIVISOR OF 1, 16, 32, OR 64. IF A CTC CHANNEL IS + ; CONFIGURED FOR THIS SERIAL PORT, THEN WE CAN ADDITIONALLY + ; APPLY A SCALER OF 1-256. +; + ; WE START BY DETERMINING THE MAXIMUM POSSIBLE SIO + ; SCALING. +; + ; WARNING: IF THE INCOMING SIO CLOCK IS THE SAME AS THE + ; CPU CLOCK AND WE USE THE 1:1 DIVISOR, THE SIO WILL NOT + ; WORK WELL. +; + PUSH BC ; MOVE WORKING DIVISOR VALUE + POP HL ; ... TO HL + LD A,L ; LOAD LSB OF DIVISOR + LD BC,$0004 ; SHIFT 0 BITS / SIO WR4 DIV 1 + LD A,L ; LOAD LSB OF DIVISOR + AND %00001111 ; DIV 16 POSSIBLE? + JR NZ,SIO_INITDEV2 ; NOPE, DONE TRYING + LD BC,$0444 ; SHIFT 4 BITS / SIO WR4 DIV 16 + LD A,L ; LOAD LSB OF DIVISOR + AND %00011111 ; DIV 32 POSSIBLE? + JR NZ,SIO_INITDEV2 ; NOPE, DONE TRYING + LD BC,$0584 ; SHIFT 5 BITS / SIO WR4 DIV 32 + LD A,L ; LOAD LSB OF DIVISOR + AND %00111111 ; DIV 32 POSSIBLE? + JR NZ,SIO_INITDEV2 ; NOPE, DONE TRYING + LD BC,$06C4 ; SHIFT 6 BITS / SIO WR4 DIV 64 +; + ; NOW APPLY THE SIO DIVISOR TO THE WORKING DIVISOR + ; AND SAVE THE RESULTANT SIO REGISTER VALUE TO APPLY LATER. +SIO_INITDEV2: + ; SHIFT BITS + XOR A ; ZERO ACCUM + OR B ; ZERO BITS TO SHIFT? + JR Z,SIO_INITDEV4 ; BYPASS SHIFTING IF SO +SIO_INITDEV3: + SRL H ; SHIFT HL RIGHT BY + RR L ; ONE BIT + DJNZ SIO_INITDEV3 ; UNTIL ALL BITS DONE +SIO_INITDEV4: + LD B,C ; MOVE SIO WR4 VALUE TO B +; + POP DE ; RESTORE DE = SERIAL CONFIG +; +#IF (SIODEBUG) + PUSH BC + PUSH HL + POP BC + PRTS(" CTCDIV=$") + CALL PRTHEXWORD + POP BC +#ENDIF +; +#IF (CTCENABLE) +; + LD A,(IY+13) ; GET CTC CHANNEL + INC A ; $FF -> 0 + JR Z,SIO_NOCTC ; NO CTC CHANNEL, BYPASS +; + ; HL HAS THE DIVISOR THAT WE WANT TO PROGRAM INTO THE + ; DESIGNATED CTC CHANNEL. HOWEVER, THE CTC REGISTER IS ONE + ; BYTE. A VALUE OF 0 MEANS 256. SO WE NEED TO VALIDATE + ; THAT HL IS BETWEEN 1 AND 256. + DEC HL ; 1-256 -> 0-255 + LD A,H ; MSB NOW MUST BE ZERO + OR A ; SET FLAGS + JR NZ,SIO_INITFAIL ; IF ANY BIT SET, FAIL + INC HL ; RESTORE HL +; + ; ALL GOOD. PROGRAM THE CTC CHANNEL + LD A,(IY+13) ; GET CTC CHANNEL + ADD A,CTCA ; ADD TO CTC BASE PORT ADR + #IF (SIODEBUG) + PRTS(" CTC=$") + CALL PRTHEXBYTE + #ENDIF + LD C,A ; AND PUT IN C FOR I/O + LD A,%01010111 ; CTCC CONTROL WORD VALUE + ; |||||||+-- 1=CONTROL WORD FLAG + ; ||||||+--- 1=SOFTWARE RESET + ; |||||+---- 1=TIME CONSTANT FOLLOWS + ; ||||+----- 0=AUTO TRIGGER WHEN TIME CONST LOADED + ; |||+------ 1=RISING EDGE TRIGGER + ; ||+------- 0=PRESCALER OF 16 (NOT USED) + ; |+-------- 1=COUNTER MODE + ; +--------- 0=NO INTERRUPTS + OUT (C),A ; PREP CTC CHANNEL + OUT (C),L ; SET CTC TIMER CONSTANT + JR SIO_INITBROK ; AND REJOIN MAIN SETUP +; +#ENDIF +; +SIO_NOCTC: + ; IF THERE IS NO CTC, THEN THE REMAINING DIVISOR + ; NEEDS TO BE EXACTLY 1 OR WE HAVE A PROBLEM. + LD A,L ; GET REMAINING DIVISOR + DEC A ; 1 -> 0 + JR Z,SIO_INITBROK ; FAIL IF NOT 1 ; SIO_INITFAIL: ; @@ -665,6 +800,28 @@ SIO_INITBROK: ; FAILS. ; SIO_INITSAFE: +; +#IF (CTCENABLE) +; + ; CHECK IF A CTC CHANNEL IS CONFIGURED + LD A,(IY+13) ; GET CTC CHANNEL + INC A ; $FF -> 0 + JR Z,SIO_INITSAFE2 ; NO CTC CHANNEL, BYPASS +; + ; IF A CTC CHANNEL IS CONFIGURED, PROGRAM IT FOR + ; SIMPLE 1:1 SCALING. + LD A,(IY+13) ; GET CTC CHANNEL + ADD A,CTCA ; ADD TO CTC BASE PORT ADR + LD C,A ; AND PUT IN C FOR I/O + LD A,%01010111 ; CTCC CONTROL WORD VALUE + OUT (C),A ; PREP CTC CHANNEL + LD A,1 ; TIMER CONSTANT IS 1 + OUT (C),A ; SET CTC TIMER CONSTANT +; +#ENDIF +; +SIO_INITSAFE2: + ; SETUP DEFAULT VALUES FOR SIO REGISTERS LD HL,SIO_INITDEFS LD DE,SIO_INITVALS LD BC,SIO_INITLEN @@ -674,7 +831,7 @@ SIO_INITGO: ; ; SET INTERRUPT VECTOR OFFSET WR2 ; -#IF (INTMODE == 2) +#IF ((INTMODE == 2) | (INTMODE == 3)) LD A,(IY+2) ; CHIP / CHANNEL SRL A ; SHIFT AWAY CHANNEL BIT LD L,SIO0_VEC ; ASSUME CHIP 0 @@ -682,7 +839,10 @@ SIO_INITGO: LD L,SIO1_VEC ; ASSUME CHIP 1 DEC A ; CHIP 1? JR Z,SIO_INITIVT ; IF SO, DO IT - CALL PANIC ; IMPOSSIBLE SITUATION + CALL SYSCHK ; IMPOSSIBLE SITUATION + LD A,ERR_NOUNIT + OR A + RET SIO_INITIVT: LD A,L ; VALUE TO A LD (SIO_WR2),A ; SAVE IT @@ -789,6 +949,8 @@ SIO_DEVICE: LD D,CIODEV_SIO ; D := DEVICE TYPE LD E,(IY) ; E := PHYSICAL UNIT LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 + LD H,(IY+14) ; H := MODE + LD L,(IY+3) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -931,10 +1093,10 @@ SIO_MAP .DB 0 ; CHIP PRESENCE BITMAP SIO0A_RCVBUF .EQU 0 SIO0B_RCVBUF .EQU 0 ; -#IF (SIOCNT >= 2) + #IF (SIOCNT >= 2) SIO1A_RCVBUF .EQU 0 SIO1B_RCVBUF .EQU 0 -#ENDIF + #ENDIF ; #ELSE ; @@ -952,7 +1114,7 @@ SIO0B_HD .DW SIO0B_BUF ; BUFFER HEAD POINTER SIO0B_TL .DW SIO0B_BUF ; BUFFER TAIL POINTER SIO0B_BUF .FILL SIO_BUFSZ,0 ; RECEIVE RING BUFFER ; -#IF (SIOCNT >= 2) + #IF (SIOCNT >= 2) ; ; SIO1 CHANNEL A RECEIVE BUFFER SIO1A_RCVBUF: @@ -968,7 +1130,7 @@ SIO1B_HD .DW SIO1B_BUF ; BUFFER HEAD POINTER SIO1B_TL .DW SIO1B_BUF ; BUFFER TAIL POINTER SIO1B_BUF .FILL SIO_BUFSZ,0 ; RECEIVE RING BUFFER ; -#ENDIF + #ENDIF ; #ENDIF ; @@ -984,8 +1146,10 @@ SIO0A_CFG: .DB SIO0A_DAT ; DATA PORT .DW SIO0ACFG ; LINE CONFIGURATION .DW SIO0A_RCVBUF ; POINTER TO RCV BUFFER STRUCT - .DW (SIO0ACLK / SIO0ADIV) & $FFFF ; CLOCK FREQ AS - .DW (SIO0ACLK / SIO0ADIV) >> 16 ; ... DWORD VALUE + .DW SIO0ACLK & $FFFF ; CLOCK FREQ AS + .DW SIO0ACLK >> 16 ; ... DWORD VALUE + .DB SIO0ACTCC ; CTC CHANNEL + .DB SIO0MODE ; MODE ; SIO_CFGSIZ .EQU $ - SIO_CFG ; SIZE OF ONE CFG TABLE ENTRY ; @@ -998,8 +1162,10 @@ SIO0B_CFG: .DB SIO0B_DAT ; DATA PORT .DW SIO0BCFG ; LINE CONFIGURATION .DW SIO0B_RCVBUF ; POINTER TO RCV BUFFER STRUCT - .DW (SIO0BCLK / SIO0BDIV) & $FFFF ; CLOCK FREQ AS - .DW (SIO0BCLK / SIO0BDIV) >> 16 ; ... DWORD VALUE + .DW SIO0BCLK & $FFFF ; CLOCK FREQ AS + .DW SIO0BCLK >> 16 ; ... DWORD VALUE + .DB SIO0BCTCC ; CTC CHANNEL + .DB SIO0MODE ; MODE ; #IF (SIOCNT >= 2) ; @@ -1012,8 +1178,10 @@ SIO1A_CFG: .DB SIO1A_DAT ; DATA PORT .DW SIO1ACFG ; LINE CONFIGURATION .DW SIO1A_RCVBUF ; POINTER TO RCV BUFFER STRUCT - .DW (SIO1ACLK / SIO1ADIV) & $FFFF ; CLOCK FREQ AS - .DW (SIO1ACLK / SIO1ADIV) >> 16 ; ... DWORD VALUE + .DW SIO1ACLK & $FFFF ; CLOCK FREQ AS + .DW SIO1ACLK >> 16 ; ... DWORD VALUE + .DB SIO1ACTCC ; CTC CHANNEL + .DB SIO1MODE ; MODE ; ; SIO1 CHANNEL B SIO1B_CFG: @@ -1024,8 +1192,10 @@ SIO1B_CFG: .DB SIO1B_DAT ; DATA PORT .DW SIO1BCFG ; LINE CONFIGURATION .DW SIO1B_RCVBUF ; POINTER TO RCV BUFFER STRUCT - .DW (SIO1BCLK / SIO1BDIV) & $FFFF ; CLOCK FREQ AS - .DW (SIO1BCLK / SIO1BDIV) >> 16 ; ... DWORD VALUE + .DW SIO1BCLK & $FFFF ; CLOCK FREQ AS + .DW SIO1BCLK >> 16 ; ... DWORD VALUE + .DB SIO1BCTCC ; CTC CHANNEL + .DB SIO1MODE ; MODE ; #ENDIF ; diff --git a/Source/HBIOS/sn76489.asm b/Source/HBIOS/sn76489.asm new file mode 100644 index 00000000..b65e9f5d --- /dev/null +++ b/Source/HBIOS/sn76489.asm @@ -0,0 +1,405 @@ +;====================================================================== +; SN76489 sound driver +; +; WRITTEN BY: DEAN NETHERTON +;====================================================================== +; +; TODO: +; 1. PROVIDE SUPPORT FOR NOISE CHANNEL +; 2. DOES THIS WORK FOR FASTER CPUS? ONLY BEEN TESTED ON A Z80 7MHZ UNIT +; +;====================================================================== +; CONSTANTS +;====================================================================== +; + +SN76489_PORT_LEFT .EQU $FC ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) +SN76489_PORT_RIGHT .EQU $F8 ; PORTS FOR ACCESSING THE SN76489 CHIP (RIGHT) +SN7_IDAT .EQU 0 +SN7_TONECNT .EQU 3 ; COUNT NUMBER OF TONE CHANNELS +SN7_NOISECNT .EQU 1 ; COUNT NUMBER OF NOISE CHANNELS +SN7_CHCNT .EQU SN7_TONECNT + SN7_NOISECNT +CHANNEL_0_SILENT .EQU $9F +CHANNEL_1_SILENT .EQU $BF +CHANNEL_2_SILENT .EQU $DF +CHANNEL_3_SILENT .EQU $FF + +SN7RATIO .EQU SN7CLK * 100 / 32 + + .ECHO "SN76489 CLOCK: " + .ECHO SN7CLK + .ECHO "\n" + +#INCLUDE "audio.inc" + +SN76489_INIT: + LD IY, SN7_IDAT ; POINTER TO INSTANCE DATA + + LD DE,STR_MESSAGELT + CALL WRITESTR + LD A, SN76489_PORT_LEFT + CALL PRTHEXBYTE + + LD DE,STR_MESSAGERT + CALL WRITESTR + LD A, SN76489_PORT_RIGHT + CALL PRTHEXBYTE +; +SN7_INIT1: + LD BC, SN7_FNTBL ; BC := FUNCTION TABLE ADDRESS + LD DE, SN7_IDAT ; DE := SN7 INSTANCE DATA PTR + CALL SND_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED + + CALL SN7_VOLUME_OFF + XOR A ; SIGNAL SUCCESS + RET + +;====================================================================== +; SN76489 DRIVER - SOUND ADAPTER (SND) FUNCTIONS +;====================================================================== +; + +SN7_RESET: + AUDTRACE(SNT_INIT) + CALL SN7_VOLUME_OFF + XOR A ; SIGNAL SUCCESS + RET + +SN7_VOLUME_OFF: + AUDTRACE(SNT_VOLOFF) + + LD A, CHANNEL_0_SILENT + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + LD A, CHANNEL_1_SILENT + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + LD A, CHANNEL_2_SILENT + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + LD A, CHANNEL_3_SILENT + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + RET + +; BIT MAPPING +; SET TONE: +; 1 CC 0 PPPP (LOW) +; 0 0 PPPPPP (HIGH) + +; 1 CC 1 VVVV + +SN7_VOLUME: + AUDTRACE(SNT_VOL) + AUDTRACE_L + AUDTRACE_CR + LD A, L + LD (SN7_PENDING_VOLUME), A + + XOR A ; SIGNAL SUCCESS + RET + +SN7_NOTE: + LD DE, SN7NOTETBL + CALL AUD_NOTE ; RETURNS PERIOD IN HL, FALL THRU + ; TO SET THIS PERIOD +SN7_PERIOD: + AUDTRACE(SNT_PERIOD) + AUDTRACE_HL + AUDTRACE_CR + + LD A, H ; IF ZERO - ERROR + OR L + JR Z, SN7_QUERY_PERIOD1 + + LD (SN7_PENDING_PERIOD), HL ;ASSUME SUCCESS + + OR A ; IF >= 401 ERROR + LD DE, $401 + SBC HL, DE + JR NC, SN7_QUERY_PERIOD1 + + XOR A ; SIGNAL SUCCESS + RET + +SN7_QUERY_PERIOD1: ; REQUESTED PERIOD IS LARGER THAN THE SN76489 CAN SUPPORT + LD A, $FF + LD L, A + LD H, A + LD (SN7_PENDING_PERIOD), HL + RET + +SN7_PLAY: + AUDTRACE(SNT_PLAY) + AUDTRACE_D + AUDTRACE_CR + + LD A, (SN7_PENDING_PERIOD + 1) + CP $FF + JR Z, SN7_PLAY1 ; PERIOD IS TOO LARGE, UNABLE TO PLAY + CALL SN7_APPLY_VOL + CALL SN7_APPLY_PRD + + XOR A ; SIGNAL SUCCESS + RET + +SN7_PLAY1: ; TURN CHANNEL VOL TO OFF AND STOP PLAYING + LD A, (SN7_PENDING_VOLUME) + PUSH AF + LD A, 0 + LD (SN7_PENDING_VOLUME), A + CALL SN7_APPLY_VOL + POP AF + LD (SN7_PENDING_VOLUME), A + + OR $FF ; SIGNAL FAILURE + RET + +SN7_QUERY: + LD A, E + CP BF_SNDQ_CHCNT + JR Z, SN7_QUERY_CHCNT + + CP BF_SNDQ_PERIOD + JR Z, SN7_QUERY_PERIOD + + CP BF_SNDQ_VOLUME + JR Z, SN7_QUERY_VOLUME + + CP BF_SNDQ_DEV + JR Z, SN7_QUERY_DEV + + OR $FF ; SIGNAL FAILURE + RET + +SN7_QUERY_CHCNT: + LD B, SN7_TONECNT + LD C, SN7_NOISECNT + XOR A + RET + +SN7_QUERY_PERIOD: + LD HL, (SN7_PENDING_PERIOD) + XOR A + RET + +SN7_QUERY_VOLUME: + LD A, (SN7_PENDING_VOLUME) + LD L, A + LD H, 0 + + XOR A + RET + +SN7_QUERY_DEV: + + LD B, SNDDEV_SN76489 + LD DE, SN76489_PORT_LEFT ; E WITH LEFT PORT + LD HL, SN76489_PORT_RIGHT ; L WITH RIGHT PORT + + XOR A + RET +; +; UTIL FUNCTIONS +; + +SN7_APPLY_VOL: ; APPLY VOLUME TO BOTH LEFT AND RIGHT CHANNELS + PUSH BC ; D CONTAINS THE CHANNEL NUMBER + PUSH AF + LD A, D + AND $3 + RLCA + RLCA + RLCA + RLCA + RLCA + OR $90 + LD B, A + + LD A, (SN7_PENDING_VOLUME) + RRCA + RRCA + RRCA + RRCA + + AND $0F + LD C, A + LD A, $0F + SUB C + AND $0F + OR B ; A CONTAINS COMMAND TO SET VOLUME FOR CHANNEL + + AUDTRACE(SNT_REGWR) + AUDTRACE_A + AUDTRACE_CR + + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + POP AF + POP BC + RET + +SN7_APPLY_PRD: + PUSH DE + PUSH BC + PUSH AF + LD HL, (SN7_PENDING_PERIOD) + + LD A, D + AND $3 + RLCA + RLCA + RLCA + RLCA + RLCA + OR $80 + LD B, A ; PERIOD COMMAND 1 - CONTAINS CHANNEL ONLY + + LD A, L ; GET LOWER 4 BITS FOR COMMAND 1 + AND $F + OR B ; A NOW CONTAINS FIRST PERIOD COMMAND + + AUDTRACE(SNT_REGWR) + AUDTRACE_A + AUDTRACE_CR + + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + LD A, L ; RIGHT SHIFT OUT THE LOWER 4 BITS + RRCA + RRCA + RRCA + RRCA + AND $F + LD B, A + + LD A, H + AND $3 + RLCA + RLCA + RLCA + RLCA ; AND PLACE IN BITS 5 AND 6 + OR B ; OR THE TWO SETS OF BITS TO MAKE 2ND PERIOD COMMAND + + AUDTRACE(SNT_REGWR) + AUDTRACE_A + AUDTRACE_CR + + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + POP AF + POP BC + POP DE + RET + +SN7_DURATION: + LD (SN7_PENDING_DURATION),HL ; SET TONE DURATION + XOR A + RET + +SN7_DEVICE: + LD D,SNDDEV_SN76489 ; D := DEVICE TYPE + LD E,0 ; E := PHYSICAL UNIT + LD C,$00 ; C := DEVICE TYPE + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,SN76489_PORT_LEFT ; L := BASE I/O ADDRESS + XOR A + RET + +SN7_FNTBL: + .DW SN7_RESET + .DW SN7_VOLUME + .DW SN7_PERIOD + .DW SN7_NOTE + .DW SN7_PLAY + .DW SN7_QUERY + .DW SN7_DURATION + .DW SN7_DEVICE +; +#IF (($ - SN7_FNTBL) != (SND_FNCNT * 2)) + .ECHO "*** INVALID SND FUNCTION TABLE ***\n" + !!!!! +#ENDIF + +SN7_PENDING_PERIOD + .DW 0 ; PENDING PERIOD (10 BITS) +SN7_PENDING_VOLUME + .DB 0 ; PENDING VOL (8 BITS -> DOWNCONVERTED TO 4 BITS AND INVERTED) +SN7_PENDING_DURATION + .DW 0 ; PENDING DURATION (16 BITS) + +STR_MESSAGELT .DB "\r\nSN76489: LEFT IO=0x$" +STR_MESSAGERT .DB ", RIGHT IO=0x$" + +#IF AUDIOTRACE +SNT_INIT .DB "\r\nSN7_INIT\r\n$" +SNT_VOLOFF .DB "\r\nSN7_VOLUME OFF\r\n$" +SNT_VOL .DB "\r\nSN7_VOLUME: $" +SNT_NOTE .DB "\r\nSN7_NOTE: $" +SNT_PERIOD .DB "\r\nSN7_PERIOD: $" +SNT_PLAY .DB "\r\nSN7_PLAY CH: $" +SNT_REGWR .DB "\r\nOUT SN76489, $" +#ENDIF + +; THE FREQUENCY BY QUARTER TONE STARTING AT A0# OCATVE 0 +; USED TO MAP EACH OCTAVE (DIV BY 2 TO JUMP AN OCTAVE UP) +; FIRST PLAYABLE NOTE WILL BE $2E +; ASSUMING A CLOCK OF 1843200 THIS MAPS TO +; 2 QUATER TONES BELOW A1#, WITH A1# AT $30 + +SN7NOTETBL: + .DW SN7RATIO / 2913 + .DW SN7RATIO / 2956 + .DW SN7RATIO / 2999 + .DW SN7RATIO / 3042 + .DW SN7RATIO / 3086 + .DW SN7RATIO / 3131 + .DW SN7RATIO / 3177 + .DW SN7RATIO / 3223 + .DW SN7RATIO / 3270 + .DW SN7RATIO / 3318 + .DW SN7RATIO / 3366 + .DW SN7RATIO / 3415 + .DW SN7RATIO / 3464 + .DW SN7RATIO / 3515 + .DW SN7RATIO / 3566 + .DW SN7RATIO / 3618 + .DW SN7RATIO / 3670 + .DW SN7RATIO / 3724 + .DW SN7RATIO / 3778 + .DW SN7RATIO / 3833 + .DW SN7RATIO / 3889 + .DW SN7RATIO / 3945 + .DW SN7RATIO / 4003 + .DW SN7RATIO / 4061 + .DW SN7RATIO / 4120 + .DW SN7RATIO / 4180 + .DW SN7RATIO / 4241 + .DW SN7RATIO / 4302 + .DW SN7RATIO / 4365 + .DW SN7RATIO / 4428 + .DW SN7RATIO / 4493 + .DW SN7RATIO / 4558 + .DW SN7RATIO / 4624 + .DW SN7RATIO / 4692 + .DW SN7RATIO / 4760 + .DW SN7RATIO / 4829 + .DW SN7RATIO / 4899 + .DW SN7RATIO / 4971 + .DW SN7RATIO / 5043 + .DW SN7RATIO / 5116 + .DW SN7RATIO / 5191 + .DW SN7RATIO / 5266 + .DW SN7RATIO / 5343 + .DW SN7RATIO / 5421 + .DW SN7RATIO / 5499 + .DW SN7RATIO / 5579 + .DW SN7RATIO / 5661 + .DW SN7RATIO / 5743 diff --git a/Source/HBIOS/spk.asm b/Source/HBIOS/spk.asm index e1575660..74df2143 100644 --- a/Source/HBIOS/spk.asm +++ b/Source/HBIOS/spk.asm @@ -1,46 +1,197 @@ +;====================================================================== +; +; BIT MODE SOUND DRIVER FOR SBC V2 USING BIT 0 OF RTC DRIVER ; ;====================================================================== -; I/O BIT DRIVER FOR CONSOLE BELL FOR SBC V2 USING BIT 0 OF RTC DRIVER +; +; LIMITATIONS - CPU FREQUENCY ADJUSTMENT LIMITED TO 1MHZ RESOLUTION +; QUARTER TONES NOT SUPPORTED +; DURATION FIXED TO 1 SECOND. +; NO VOLUME ADJUSTMENT DUE TO HARDWARE LIMITATION ;====================================================================== ; -SPK_INIT: - CALL NEWLINE ; FORMATTING +; DRIVER FUNCTION TABLE AND INSTANCE DATA +; +SP_FNTBL: + .DW SP_STUB ; SP_RESET + .DW SP_STUB ; SP_VOLUME + .DW SP_PERIOD + .DW SP_NOTE + .DW SP_PLAY + .DW SP_QUERY + .DW SP_DURATION + .DW SP_DEVICE +; +#IF (($ - SP_FNTBL) != (SND_FNCNT * 2)) + .ECHO "*** INVALID SND FUNCTION TABLE ***\n" + !!!!! +#ENDIF +; +SP_IDAT .EQU 0 ; NO INSTANCE DATA ASSOCIATED WITH THIS DEVICE +; +SP_TONECNT .EQU 1 ; COUNT NUMBER OF TONE CHANNELS +SP_NOISECNT .EQU 0 ; COUNT NUMBER OF NOISE CHANNELS +; +SP_RTCIOMSK .EQU 00000100B +; +; FOR OTHER DRIVERS, THE PERIOD VALUE FOR THE TONE IS STORED AT PENDING_PERIOD +; FOR THE SPK DRIVER THE ADDRESS IN THE TONE TABLE IS STORED IN PENDING_PERIOD +; +SP_PENDING_PERIOD .DW SP_NOTE_C8 ; PENDING PERIOD (16 BITS) +SP_PENDING_VOLUME .DB $FF ; PENDING VOL (8 BITS) +SP_PENDING_DURATION .DW 0 ; PENDING DURATION (16 BITS) +; +;====================================================================== +; DRIVER INITIALIZATION +;====================================================================== +; +SP_INIT: + LD IY, SP_IDAT ; SETUP FUNCTION TABLE + LD BC, SP_FNTBL ; POINTER TO INSTANCE DATA + LD DE, SP_IDAT ; BC := FUNCTION TABLE ADDRESS + CALL SND_ADDENT ; DE := INSTANCE DATA PTR +; + CALL NEWLINE ; ANNOUNCE DEVICE PRTS("SPK: IO=0x$") LD A,RTCIO CALL PRTHEXBYTE - CALL SPK_SETTBL - CALL SPK_BEEP ; PLAY A NOTE + CALL SP_SETTBL ; SETUP TONE TABLE + CALL SP_PLAY ; PLAY DEFAULT NOTE XOR A RET ; -; SETUP THE SPEAKER NOTE TABLE ACCORDING TO THE CPU SPEED. -; FREQUENCY ACCURACY DECREASES AS CLOCK SPEED MULITPLIER INCREASES. -; 1MHZ ERROR MAY OCCUR IF CPU CLOCK IS UNDER. I.E 3.999 = 3MHZ - -SPK_SETTBL: - LD A,(CB_CPUMHZ) ; GET CPU SPEED. - LD C,A - - LD B,SPK_NOTCNT ; SET NUMBER OF NOTES TO - LD HL,SPK_TUNTBL+2 ; ADJUST AND START POINT - -SPK_SETTBL2: +;====================================================================== +; SOUND DRIVER FUNCTION - RESET +;====================================================================== +; +;SP_RESET: +; XOR A ; SUCCESSFULL RESET +; RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - VOLUME +;====================================================================== +; +;SP_VOLUME: +; XOR A ; SIGNAL SUCCESS +; RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - PERIOD +;====================================================================== +; +SP_PERIOD: + LD (SP_PENDING_PERIOD), HL ; SAVE AND RETURN SUCCESSFUL +SP_STUB: + XOR A + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - NOTE +;====================================================================== +; +SP_NOTE: +; CALL PRTHEXWORDHL +; CALL PC_COLON PUSH HL - LD A,(HL) ; READ - LD E,A ; IN - INC HL ; THE - LD A,(HL) ; 1MHZ - LD D,A ; NOTE - + PUSH DE ; ON ENTRY HL IS A NOTE INDEX + LD A,L ; CONVERT THIS NOTE INDEX + AND 00000011B ; TO THE ASSOCIATED ENTRY + JR Z,SP_NOTE1 ; IN THE TUNE TABLE. +; + LD HL,$FFFF ; QUARTER NOTES + JR SP_NOTE2 ; NOT SUPPORTED +; +SP_NOTE1: + LD DE,SP_TUNTBL ; SAVE THIS ADDRESS AS + ADD HL,DE ; THE PERIOD +SP_NOTE2: +; CALL PRTHEXWORDHL +; CALL NEWLINE + LD (SP_PENDING_PERIOD),HL + POP DE + POP HL + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - QUERY AND SUBFUNCTIONS +;====================================================================== +; +SP_QUERY: + LD A, E + CP BF_SNDQ_CHCNT ; SUB FUNCTION 01 + JR Z, SP_QUERY_CHCNT +; + CP BF_SNDQ_VOLUME ; SUB FUNCTION 02 + JR Z, SP_QUERY_VOLUME +; + CP BF_SNDQ_PERIOD ; SUB FUNCTION 03 + JR Z, SP_QUERY_PERIOD +; + CP BF_SNDQ_DEV ; SUB FUNCTION 04 + JR Z, SP_QUERY_DEV +; + OR $FF ; SIGNAL FAILURE + RET +; +SP_QUERY_CHCNT: + LD BC,(SP_TONECNT*256)+SP_NOISECNT ; RETURN NUMBER OF + XOR A ; TONE AND NOISE + RET ; CHANNELS IN BC +; +SP_QUERY_PERIOD: + LD HL, (SP_PENDING_PERIOD) ; RETURN 16-BIT PERIOD + XOR A ; IN HL REGISTER + RET +; +SP_QUERY_VOLUME: + LD L, 255 ; RETURN 8-BIT VOLUME + XOR A ; IN L REGISTER + RET +; +SP_QUERY_DEV: + LD B, SNDDEV_BITMODE ; RETURN DEVICE IDENTIFIER + LD DE, (RTCIO*256)+SP_RTCIOMSK ; AND ADDRESS AND DATA PORT + XOR A + RET +; +;====================================================================== +; INITIALIZE THE TONE TABLE - ONLY ACCURATE FOR 1MHZ INCREMENTS +;====================================================================== +; +SP_SETTBL: + LD HL,(CB_CPUKHZ) ; GET CPU SPEED. + LD DE,1000 ; CONVERT TO MHZ + CALL DIV16 +; + LD DE,900 ; IF MHZ IS WITHIN 10% OF + SBC HL,DE ; NEXT INTEGER INCREMENT + JP M,SP_SETTBL3 ; THEN BUMP UP. I.E. 9.928MHZ + INC C ; BECOMES 10MHZ +; +SP_SETTBL3: + LD B,SP_NOTCNT ; SET NUMBER OF NOTES TO + LD HL,SP_TUNTBL+2 ; ADJUST AND START POINT +; +SP_SETTBL2: + PUSH HL + LD E,(HL) ; READ IN + INC HL ; THE 1MHZ + LD D,(HL) ; NOTE +; PUSH BC LD B,C - LD HL,0 ; MULTIPLY -SPK_SETTBL1: ; 1MHZ NOTE - ADD HL,DE ; VALUE BY - DJNZ SPK_SETTBL1 ; SYSTEM MHZ + LD HL,0 ; MULTIPLY 1MHZ +SP_SETTBL1: ; NOTE VALUE BY + ADD HL,DE ; SYSTEM MHZ + JR NC,SP_SETBL4 + LD HL,$FFFF ; FOR CPU > 10MHz + LD B,1 ; HANDLE OVERFLOW +SP_SETBL4: + DJNZ SP_SETTBL1 POP BC ; - LD DE,30 ; ADD OVEREAD + LD DE,15 ; ADD OVERHEAD ADD HL,DE ; COMPENSATION ; POP DE ; RECALL NOTE @@ -52,34 +203,49 @@ SPK_SETTBL1: ; 1MHZ NOTE INC HL ; NOTE INC HL ; AND MOVE INC HL ; TO NEXT - - DJNZ SPK_SETTBL2 ; NEXT NOTE +; + DJNZ SP_SETTBL2 ; NEXT NOTE RET - -SPK_BEEP: - LD HL,SPK_NOTE_C8 ; SELECT NOTE ; - LD A,(HL) ; LOAD 1ST ARG +;====================================================================== +; SOUND DRIVER FUNCTION - PLAY +;====================================================================== +; +SP_PLAY: + LD HL,(SP_PENDING_PERIOD) ; SELECT NOTE +; + LD A,$FF ; EXIT WITH ERROR + CP H ; STATUS IF INVALID + JR NZ,SP_PLAY1 ; PERIOD ($FFFF) + CP L + RET Z + +SP_PLAY1: + LD E,(HL) ; LOAD 1ST ARG INC HL ; IN DE - LD E,A - LD A,(HL) + LD D,(HL) INC HL - LD D,A ; - LD A,(HL) ; LOAD 2ND ARG + LD C,(HL) ; LOAD 2ND ARG INC HL ; IN BC - LD C,A - LD A,(HL) + LD B,(HL) INC HL - LD B,A +; +; LD A,$FF ; EXIT WITH ERROR + CP B ; STATUS IF INVALID + JR NZ,SP_PLAY2 ; NOTE ($FFFF) + CP C + RET Z +; +SP_PLAY2: PUSH BC ; SETUP ARG IN HL POP HL ; - CALL SPK_BEEPER ; PLAY +; CALL SP_BEEPER ; PLAY ; - RET +; RET ; -; The following SPK_BEEPER routine is a modification of code from +; The following SP_BEEPER routine is a modification of code from ; "The Complete SPECTRUM ROM DISSASSEMBLY" by Dr Ian Logan & Dr Frank O’Hara ; ; https://www.esocop.org/docs/CompleteSpectrumROMDisassemblyThe.pdf @@ -87,9 +253,9 @@ SPK_BEEP: ; DE Number of passes to make through the sound generation loop ; HL Loop delay parameter ; -SPK_BEEPER: +SP_BEEPER: PUSH IX - DI ; Disable the interrupt for the duration of a 'beep'. + HB_DI ; Disable the interrupt for the duration of a 'beep'. LD A,L ; Save L temporarily. SRL L ; Each '1' in the L register is to count 4 T states, but take INT (L/4) and count 16 T states instead. SRL L @@ -118,7 +284,7 @@ BE_H_L_LP: ; ; The loudspeaker is now alternately activated and deactivated. ; - XOR %00000100 ; Flip bit 2. + XOR SP_RTCIOMSK ; Flip bit 2. OUT (RTCIO),A ; Perform the 'OUT' operation, leaving other bits unchanged. LD B,H ; Reset the B register. LD C,A ; Save the A register. @@ -142,122 +308,151 @@ BE_AGAIN: INC C ; Add 16 T states as this path is shorter. JP (IX) ; Jump back. BE_END: - EI + HB_EI POP IX + RET ; ALWAYS EXITS WITH SUCCESS STATUS (A=0) +; +;====================================================================== +; SOUND DRIVER FUNCTION - DURATION +;====================================================================== +; +SP_DURATION: + LD (SP_PENDING_DURATION),HL; SET TONE PERIOD TO ZERO + XOR A RET ; -; STANDARD ONE SECOND TONE TABLES AT 1MHZ (UNCOMPENSATED). FOR SPK_BEEPER, FIRST WORD LOADED INTO DE, SECOND INTO HL -; -; EXCEL SPREADSHEET FOR CALCULATION CAN BE FOUND HERE: -; -; https://www.retrobrewcomputers.org/lib/exe/fetch.php?media=boards:sbc:sbc_v2:sbc_v2-004:spk_beep_tuntbl.xlsx -; -SPK_TUNTBL: - .DW $13, $191A ; D - .DW $14, $17B3 ; E0 - .DW $15, $165E ; F0 - .DW $17, $151E ; F - .DW $18, $13EE ; G0 - .DW $19, $12CF ; G - .DW $1B, $11C1 ; A0 - .DW $1D, $10C1 ; A - .DW $1E, $FD1 ; B0 - .DW $20, $EEE ; C1 - .DW $22, $E17 ; C - .DW $24, $D4D ; D1 - .DW $26, $C8E ; D - .DW $29, $BD9 ; E1 - .DW $2B, $B2F ; F1 - .DW $2E, $A8E ; F - .DW $31, $9F7 ; G1 - .DW $33, $968 ; G - .DW $37, $8E0 ; A1 - .DW $3A, $861 ; A - .DW $3D, $7E8 ; B1 - .DW $41, $777 ; C2 - .DW $45, $70B ; C - .DW $49, $6A6 ; D2 - .DW $4D, $647 ; D - .DW $52, $5EC ; E2 - .DW $57, $597 ; F2 - .DW $5C, $547 ; F - .DW $62, $4FB ; G2 - .DW $67, $4B3 ; G - .DW $6E, $470 ; A2 - .DW $74, $430 ; A - .DW $7B, $3F4 ; B2 - .DW $82, $3BB ; C3 - .DW $8A, $385 ; C - .DW $92, $353 ; D3 - .DW $9B, $323 ; D - .DW $A4, $2F6 ; E3 - .DW $AE, $2CB ; F3 - .DW $B9, $2A3 ; F - .DW $C4, $27D ; G3 - .DW $CF, $259 ; G - .DW $DC, $238 ; A3 - .DW $E9, $218 ; A - .DW $F6, $1FA ; B3 - .DW $105, $1DD ; C4 - .DW $115, $1C2 ; C - .DW $125, $1A9 ; D4 - .DW $137, $191 ; D - .DW $149, $17B ; E4 - .DW $15D, $165 ; F4 - .DW $171, $151 ; F - .DW $188, $13E ; G4 - .DW $19F, $12C ; G - .DW $1B8, $11C ; A4 - .DW $1D2, $10C ; A - .DW $1ED, $FD ; B4 - .DW $20B, $EE ; C5 - .DW $22A, $E1 ; C - .DW $24B, $D4 ; D5 - .DW $26E, $C8 ; D - .DW $293, $BD ; E5 - .DW $2BA, $B2 ; F5 - .DW $2E3, $A8 ; F - .DW $30F, $9F ; G5 - .DW $33E, $96 ; G - .DW $370, $8E ; A5 - .DW $3A4, $86 ; A - .DW $3DB, $7E ; B5 - .DW $416, $77 ; C6 - .DW $454, $70 ; C - .DW $496, $6A ; D6 - .DW $4DC, $64 ; D - .DW $526, $5E ; E6 - .DW $574, $59 ; F6 - .DW $5C7, $54 ; F - .DW $61F, $4F ; G6 - .DW $67D, $4B ; G - .DW $6E0, $47 ; A6 - .DW $748, $43 ; A - .DW $7B7, $3F ; B6 - .DW $82D, $3B ; C7 - .DW $8A9, $38 ; C - .DW $92D, $35 ; D7 - .DW $9B9, $32 ; D - .DW $A4D, $2F ; E7 - .DW $AE9, $2C ; F7 - .DW $B8F, $2A ; F - .DW $C3F, $27 ; G7 - .DW $CFA, $25 ; G - .DW $DC0, $23 ; A7 - .DW $E91, $21 ; A - .DW $F6F, $1F ; B7 -SPK_NOTE_C8: - .DW $105A, $1D ; C8 - .DW $1152, $1C ; C - .DW $125A, $1A ; D8 - .DW $1372, $19 ; D - .DW $149A, $17 ; E8 - .DW $15D3, $16 ; F8 - .DW $171F, $15 ; F - .DW $187F, $13 ; G8 - .DW $19F4, $12 ; G - .DW $1B80, $11 ; A8 - .DW $1D22, $10 ; A - .DW $1EDE, $F ; B8 - -SPK_NOTCNT .EQU ($-SPK_TUNTBL) / 4 +;====================================================================== +; SOUND DRIVER FUNCTION - DEVICE +;====================================================================== +; +SP_DEVICE: + LD D,SNDDEV_BITMODE ; D := DEVICE TYPE + LD E,0 ; E := PHYSICAL UNIT + LD C,$00 ; C := DEVICE TYPE + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,RTCIO ; L := BASE I/O ADDRESS + XOR A + RET +; +;====================================================================== +; +; STANDARD ONE SECOND TONE TABLES AT 1MHZ. +; FOR SP_BEEPER ROUTINE, FIRST WORD LOADED INTO DE, SECOND INTO HL +; +;====================================================================== +; +#DEFINE SP_TONESET(SP_FREQ) .DW SP_FREQ/100, 12500000/SP_FREQ +; +SP_TUNTBL: + SP_TONESET(1635) ; C0 + SP_TONESET(1732) ; C + SP_TONESET(1835) ; D0 + SP_TONESET(1945) ; D + SP_TONESET(2060) ; E0 + SP_TONESET(2183) ; F0 + SP_TONESET(2312) ; F + SP_TONESET(2450) ; G0 + SP_TONESET(2596) ; G + SP_TONESET(2750) ; A0 + SP_TONESET(2914) ; A + SP_TONESET(3087) ; B0 + SP_TONESET(3270) ; C1 + SP_TONESET(3465) ; C + SP_TONESET(3671) ; D1 + SP_TONESET(3889) ; D + SP_TONESET(4120) ; E1 + SP_TONESET(4365) ; F1 + SP_TONESET(4625) ; F + SP_TONESET(4900) ; G1 + SP_TONESET(5191) ; G + SP_TONESET(5500) ; A1 + SP_TONESET(5827) ; A + SP_TONESET(6174) ; B1 + SP_TONESET(6541) ; C2 + SP_TONESET(6930) ; C + SP_TONESET(7342) ; D2 + SP_TONESET(7778) ; D + SP_TONESET(8241) ; E2 + SP_TONESET(8731) ; F2 + SP_TONESET(9250) ; F + SP_TONESET(9800) ; G2 + SP_TONESET(10383) ; G + SP_TONESET(11000) ; A2 + SP_TONESET(11654) ; A + SP_TONESET(12347) ; B2 + SP_TONESET(13081) ; C3 + SP_TONESET(13859) ; C + SP_TONESET(14683) ; D3 + SP_TONESET(15556) ; D + SP_TONESET(16481) ; E3 + SP_TONESET(17461) ; F3 + SP_TONESET(18500) ; F + SP_TONESET(19600) ; G3 + SP_TONESET(20765) ; G + SP_TONESET(22000) ; A3 + SP_TONESET(23308) ; A + SP_TONESET(24694) ; B3 + SP_TONESET(26163) ; C4 + SP_TONESET(27718) ; C + SP_TONESET(29366) ; D4 + SP_TONESET(31113) ; D + SP_TONESET(32963) ; E4 + SP_TONESET(34923) ; F4 + SP_TONESET(36999) ; F + SP_TONESET(39200) ; G4 + SP_TONESET(41530) ; G + SP_TONESET(44000) ; A4 + SP_TONESET(46616) ; A + SP_TONESET(49388) ; B4 + SP_TONESET(52325) ; C5 + SP_TONESET(55437) ; C + SP_TONESET(58733) ; D5 + SP_TONESET(62225) ; D + SP_TONESET(65925) ; E5 + SP_TONESET(69846) ; F5 + SP_TONESET(73999) ; F + SP_TONESET(78399) ; G5 + SP_TONESET(83061) ; G + SP_TONESET(88000) ; A5 + SP_TONESET(93233) ; A + SP_TONESET(98777) ; B5 + SP_TONESET(104650) ; C6 + SP_TONESET(110873) ; C + SP_TONESET(117466) ; D6 + SP_TONESET(124451) ; D + SP_TONESET(131851) ; E6 + SP_TONESET(139691) ; F6 + SP_TONESET(147998) ; F + SP_TONESET(156798) ; G6 + SP_TONESET(166122) ; G + SP_TONESET(179000) ; A6 + SP_TONESET(186466) ; A + SP_TONESET(197553) ; B6 + SP_TONESET(209300) ; C7 + SP_TONESET(221746) ; C + SP_TONESET(234932) ; D7 + SP_TONESET(248902) ; D + SP_TONESET(263702) ; E7 + SP_TONESET(279383) ; F7 + SP_TONESET(295996) ; F + SP_TONESET(313596) ; G7 + SP_TONESET(332244) ; G + SP_TONESET(352000) ; A7 + SP_TONESET(372931) ; A + SP_TONESET(395107) ; B7 +SP_NOTE_C8: + SP_TONESET(418601) ; C8 + SP_TONESET(443492) ; C + SP_TONESET(469863) ; D8 + SP_TONESET(497803) ; D + SP_TONESET(527404) ; E8 + SP_TONESET(558765) ; F8 + SP_TONESET(591991) ; F + SP_TONESET(627193) ; G8 + SP_TONESET(664488) ; G + SP_TONESET(704000) ; A8 + SP_TONESET(745862) ; A + SP_TONESET(790213) ; B8 +; +SP_NOTCNT .EQU ($-SP_TUNTBL) / 4 +; diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 9a51672a..55b266d9 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -2,7 +2,7 @@ ; the requested build configuraton file to bring in platform specifics. ; There are several hardware platforms supported by SBC. -; 1. SBC Z80 SBC (v1 or v2) w/ ECB interface +; 1. SBC Z80 SBC (v1 or v2) w/ ECB interface ; 2. ZETA Standalone Z80 SBC w/ SBC compatibility ; 3. ZETA2 Second version of ZETA with enhanced memory bank switching ; 4. N8 MSX-ish Z180 SBC w/ onboard video and sound @@ -12,7 +12,7 @@ ; 8. RCZ180 RC2014 based system with Z180 CPU ; 9. EZZ80 Easy Z80, Z80 SBC w/ RC2014 bus and CTC ; 10. SCZ180 Steve Cousins Z180 based system -; 11. DYNO Steve Garcia's Dyno Micro-ATX Motherboard +; 11. DYNO Steve Garcia's Dyno Micro-ATX Motherboard ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; @@ -20,8 +20,8 @@ ; #INCLUDE "../ver.inc" ; ADD BIOSVER ; -FALSE .EQU 0 -TRUE .EQU ~FALSE +FALSE .EQU 0 +TRUE .EQU ~FALSE ; ; DEBUGGING OPTIONS ; @@ -30,6 +30,16 @@ USEXIO .EQU 1 ; BASIC SERIAL DRIVER USEMIO .EQU 2 ; MEMORY BUFFER DRIVER WBWDEBUG .EQU USENONE ; +; DIAGNOSTIC LEVEL OPTIONS +; +DL_NONE .EQU 0 ; HBIOS DISPLAY NO MESSAGES +DL_CRITICAL .EQU 4 ; HBIOS DISPLAY CRITICAL ERROR MESSAGES +DL_ERROR .EQU 8 ; HBIOS DISPLAYS ALL ERROR MESSAGES +DL_WARNING .EQU 12 ; HBIOS DISPLAYS WARNING MESSAGES +DL_INFO .EQU 16 ; HBIOS DISPLAYS INFORMATIONAL MESSAGES +DL_DETAIL .EQU 20 ; HBIOS DISPLAYS DETAILED DIAGNOSTIC MESSAGES +DL_VERBOSE .EQU 24 ; HBIOS DISPLAYS ANYTHING IT KNOWS HOW TO +; ; PRIMARY HARDWARE PLATFORMS ; PLT_SBC .EQU 1 ; SBC ECB Z80 SBC @@ -58,6 +68,11 @@ BIOS_NONE .EQU 0 ; NO BIOS TYPE DEFINED BIOS_WBW .EQU 1 ; ROMWBW HBIOS BIOS_UNA .EQU 2 ; UNA UBIOS ; +; DEFAULT HBIOS DIAGNOSTIC LEVEL +; WILL ULTIMATELY BE MOVED TO CONFIG FILE +; +DIAGLVL .EQU DL_CRITICAL +; ; MEMORY MANAGERS ; MM_NONE .EQU 0 @@ -65,6 +80,8 @@ MM_SBC .EQU 1 ; ORIGINAL N8VEM/RBC Z80 SBC BANKED MEMORY MM_Z2 .EQU 2 ; 16K X 4 BANKED MEMORY INTRODUCED ON ZETA2 MM_N8 .EQU 3 ; Z180 CUSTOMIZED FOR N8 MEMORY EXTENSIONS MM_Z180 .EQU 4 ; Z180 NATIVE MEMORY MANAGER +MM_Z280 .EQU 5 ; Z280 NATIVE MEMORY MANAGER +MM_ZRC .EQU 6 ; ZRC BANK SWITCHING ; ; BOOT STYLE ; @@ -89,26 +106,12 @@ FDM360 .EQU 2 ; 5.25" FLOPPY, 360KB, 2 SIDES, 40 TRKS, 9 SECTORS FDM120 .EQU 3 ; 5.25" FLOPPY, 1.2MB, 2 SIDES, 80 TRKS, 15 SECTORS FDM111 .EQU 4 ; 8" FLOPPY, 1.11MB, 2 SIDES, 74 TRKS, 15 SECTORS ; -; MEDIA ID VALUES -; -MID_NONE .EQU 0 -MID_MDROM .EQU 1 -MID_MDRAM .EQU 2 -MID_RF .EQU 3 -MID_HD .EQU 4 -MID_FD720 .EQU 5 -MID_FD144 .EQU 6 -MID_FD360 .EQU 7 -MID_FD120 .EQU 8 -MID_FD111 .EQU 9 -; ; ZILOG CTC MODE SELECTIONS ; CTCMODE_NONE .EQU 0 ; NO CTC -CTCMODE_ZP .EQU 1 ; ZILOG PERIPHERALS ECB CTC -CTCMODE_Z2 .EQU 2 ; ZETA2 ONBOARD CTC -CTCMODE_EZ .EQU 3 ; EASY Z80 ONBOARD CTC -CTCMODE_RC .EQU 4 ; RC2014 CTC MODULE (ALSO KIO) +CTCMODE_CTR .EQU 1 ; CTC COUNTER +CTCMODE_TIM16 .EQU 2 ; CTC TIMER W/ DIV 16 +CTCMODE_TIM256 .EQU 3 ; CTC TIMER W/ DIV 256 ; ; DS RTC MODE SELECTIONS ; @@ -119,10 +122,10 @@ DSRTCMODE_MFPIC .EQU 2 ; MF/PIC VARIANT ; SIO MODE SELECTIONS ; SIOMODE_NONE .EQU 0 -SIOMODE_RC .EQU 1 ; RC2014 SIO MODULE (SPENCER OWEN) -SIOMODE_SMB .EQU 2 ; RC2014 SIO MODULE (SCOTT BAKER) -SIOMODE_ZP .EQU 3 ; ECB-ZILOG PERIPHERALS BOARD -SIOMODE_EZZ80 .EQU 4 ; EASY Z80 ON-BOARD SIO/0 +SIOMODE_STD .EQU 1 ; STD SIO REG CFG (EZZ80, KIO) +SIOMODE_RC .EQU 2 ; RC2014 SIO MODULE (SPENCER OWEN) +SIOMODE_SMB .EQU 3 ; RC2014 SIO MODULE (SCOTT BAKER) +SIOMODE_ZP .EQU 4 ; ECB-ZILOG PERIPHERALS BOARD ; ; TYPE OF CONSOLE BELL TO USE ; @@ -142,6 +145,7 @@ FDMODE_DIO3 .EQU 6 ; DISKIO V3 FDMODE_RCSMC .EQU 7 ; RC2014 SMC 9266 @ $40 (SCOTT BAKER) FDMODE_RCWDC .EQU 8 ; RC2014 WDC 37C65 @ $40 (SCOTT BAKER) FDMODE_DYNO .EQU 9 ; DYNO WDC 37C65 @ $84 +FDMODE_EPFDC .EQU 10 ; RC2014 ETCHED PIXELS FDC ; ; IDE MODE SELECTIONS ; @@ -181,12 +185,14 @@ AYMODE_N8 .EQU 1 ; N8 BUILT-IN SOUND AYMODE_SCG .EQU 2 ; SCG ECB BOARD AYMODE_RCZ80 .EQU 3 ; RC2014 SOUND MODULE BY ED BRINDLEY ON Z80 AYMODE_RCZ180 .EQU 4 ; RC2014 SOUND MODULE BY ED BRINDLEY ON Z180 +AYMODE_MSX .EQU 5 ; RC2014 SOUND MODULE REV6 BY ED BRINDLEY ON Z80/Z180 AT MSX PORTS ; ; TMS VIDEO MODE SELECTIONS ; TMSMODE_NONE .EQU 0 TMSMODE_SCG .EQU 1 ; SCG ECB BOARD TMSMODE_N8 .EQU 2 ; N8 BUILT-IN VIDEO +TMSMODE_RC .EQU 3 ; RC2014 BUILT-IN VIDEO ; ; SERIAL DEVICE CONFIGURATION CONSTANTS ; @@ -208,7 +214,7 @@ SER_STOP2 .EQU 1 << 2 ; AND STORED AS 5 BITS: YXXXX ; SER_BAUD75 .EQU $00 << 8 -SER_BAUD150 .EQU $01 << 8 +SER_BAUD150 .EQU $01 << 8 SER_BAUD300 .EQU $02 << 8 SER_BAUD600 .EQU $03 << 8 SER_BAUD1200 .EQU $04 << 8 @@ -218,34 +224,34 @@ SER_BAUD9600 .EQU $07 << 8 SER_BAUD19200 .EQU $08 << 8 SER_BAUD38400 .EQU $09 << 8 SER_BAUD76800 .EQU $0A << 8 -SER_BAUD153600 .EQU $0B << 8 -SER_BAUD307200 .EQU $0C << 8 -SER_BAUD614400 .EQU $0D << 8 -SER_BAUD1228800 .EQU $0E << 8 -SER_BAUD2457600 .EQU $0F << 8 -SER_BAUD225 .EQU $10 << 8 -SER_BAUD450 .EQU $11 << 8 -SER_BAUD900 .EQU $12 << 8 -SER_BAUD1800 .EQU $13 << 8 -SER_BAUD3600 .EQU $14 << 8 -SER_BAUD7200 .EQU $15 << 8 -SER_BAUD14400 .EQU $16 << 8 -SER_BAUD28800 .EQU $17 << 8 -SER_BAUD57600 .EQU $18 << 8 +SER_BAUD153600 .EQU $0B << 8 +SER_BAUD307200 .EQU $0C << 8 +SER_BAUD614400 .EQU $0D << 8 +SER_BAUD1228800 .EQU $0E << 8 +SER_BAUD2457600 .EQU $0F << 8 +SER_BAUD225 .EQU $10 << 8 +SER_BAUD450 .EQU $11 << 8 +SER_BAUD900 .EQU $12 << 8 +SER_BAUD1800 .EQU $13 << 8 +SER_BAUD3600 .EQU $14 << 8 +SER_BAUD7200 .EQU $15 << 8 +SER_BAUD14400 .EQU $16 << 8 +SER_BAUD28800 .EQU $17 << 8 +SER_BAUD57600 .EQU $18 << 8 SER_BAUD115200 .EQU $19 << 8 SER_BAUD230400 .EQU $1A << 8 SER_BAUD460800 .EQU $1B << 8 -SER_BAUD921600 .EQU $1C << 8 -SER_BAUD1843200 .EQU $1D << 8 -SER_BAUD3686400 .EQU $1E << 8 -SER_BAUD7372800 .EQU $1F << 8 +SER_BAUD921600 .EQU $1C << 8 +SER_BAUD1843200 .EQU $1D << 8 +SER_BAUD3686400 .EQU $1E << 8 +SER_BAUD7372800 .EQU $1F << 8 ; SER_XON .EQU 1 << 6 SER_DTR .EQU 1 << 7 SER_RTS .EQU 1 << 13 ; -SER_75_8N1 .EQU SER_BAUD75 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_150_8N1 .EQU SER_BAUD150 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_75_8N1 .EQU SER_BAUD75 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_150_8N1 .EQU SER_BAUD150 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_300_8N1 .EQU SER_BAUD300 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_600_8N1 .EQU SER_BAUD600 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_1200_8N1 .EQU SER_BAUD1200 | SER_DATA8 | SER_PARNONE | SER_STOP1 @@ -255,27 +261,27 @@ SER_9600_8N1 .EQU SER_BAUD9600 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_19200_8N1 .EQU SER_BAUD19200 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_38400_8N1 .EQU SER_BAUD38400 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_76800_8N1 .EQU SER_BAUD76800 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_153600_8N1 .EQU SER_BAUD153600 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_307200_8N1 .EQU SER_BAUD307200 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_614400_8N1 .EQU SER_BAUD614400 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_1228800_8N1 .EQU SER_BAUD1228800 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_2457600_8N1 .EQU SER_BAUD2457600 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_225_8N1 .EQU SER_BAUD225 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_450_8N1 .EQU SER_BAUD450 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_900_8N1 .EQU SER_BAUD900 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_1800_8N1 .EQU SER_BAUD1800 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_3600_8N1 .EQU SER_BAUD3600 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_7200_8N1 .EQU SER_BAUD7200 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_14400_8N1 .EQU SER_BAUD14400 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_28800_8N1 .EQU SER_BAUD28800 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_57600_8N1 .EQU SER_BAUD57600 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_153600_8N1 .EQU SER_BAUD153600 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_307200_8N1 .EQU SER_BAUD307200 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_614400_8N1 .EQU SER_BAUD614400 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_1228800_8N1 .EQU SER_BAUD1228800 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_2457600_8N1 .EQU SER_BAUD2457600 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_225_8N1 .EQU SER_BAUD225 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_450_8N1 .EQU SER_BAUD450 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_900_8N1 .EQU SER_BAUD900 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_1800_8N1 .EQU SER_BAUD1800 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_3600_8N1 .EQU SER_BAUD3600 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_7200_8N1 .EQU SER_BAUD7200 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_14400_8N1 .EQU SER_BAUD14400 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_28800_8N1 .EQU SER_BAUD28800 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_57600_8N1 .EQU SER_BAUD57600 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_115200_8N1 .EQU SER_BAUD115200 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_230400_8N1 .EQU SER_BAUD230400 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_460800_8N1 .EQU SER_BAUD460800 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_921600_8N1 .EQU SER_BAUD921600 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_1843200_8N1 .EQU SER_BAUD1843200 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_3686400_8N1 .EQU SER_BAUD3686400 | SER_DATA8 | SER_PARNONE | SER_STOP1 -SER_7372800_8N1 .EQU SER_BAUD7372800 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_921600_8N1 .EQU SER_BAUD921600 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_1843200_8N1 .EQU SER_BAUD1843200 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_3686400_8N1 .EQU SER_BAUD3686400 | SER_DATA8 | SER_PARNONE | SER_STOP1 +SER_7372800_8N1 .EQU SER_BAUD7372800 | SER_DATA8 | SER_PARNONE | SER_STOP1 ; ; TERMENABLE CONTROLS INCLUSION OF TERMINAL PSEUDO-DEVICE DRIVER ; IT IS SET TO TRUE BY THE INCLUSION OF ANY VDA DRIVER. @@ -299,13 +305,13 @@ KBD_DE .EQU 1 ; GERMAN ; ; EMULATION TYPES ; -EMUTYP_NONE .EQU 0 ; NONE -EMUTYP_TTY .EQU 1 ; TTY -EMUTYP_ANSI .EQU 2 ; ANSI +EMUTYP_NONE .EQU 0 ; NONE +EMUTYP_TTY .EQU 1 ; TTY +EMUTYP_ANSI .EQU 2 ; ANSI ; ; DEVICE DRIVER TO BE INITIALIZED FIRST. FIRST CIO DRIVER, UNIT 0 INITIALIZED BECOMES PRIMARY CONSOLE. ; IS AN INDEX INTO THE ENABLED INITIALIZATION DRIVER LIST i.e. ASCI, UART, SIO, ACIA, PIO, UF ETC. -; EXAMPLE: IF ONLY UART, SIO AND PIO ARE ENABLE AND THE SIO IS DESIRED AS THE PRIMARY CONSOLE, +; EXAMPLE: IF ONLY UART, SIO AND PIO ARE ENABLE AND THE SIO IS DESIRED AS THE PRIMARY CONSOLE, ; SET FORCECON TO 2 IN YOUR CUSTOM CONFIGURATION FILE i.e. "FORCECON: .SET 2" ; FORCECON .EQU 0 ; DEFAULT IS TO FOLLOW NORMAL SEQUENCE @@ -327,6 +333,9 @@ FORCECON .EQU 0 ; DEFAULT IS TO FOLLOW NORMAL SEQUENCE #IF (CPUFAM == CPU_Z180) #INCLUDE "z180.inc" #ENDIF + #IF (CPUFAM == CPU_Z280) + #INCLUDE "z280.inc" + #ENDIF #IF (EIPCENABLE) #INCLUDE "eipc.inc" #ENDIF @@ -345,11 +354,59 @@ CPUKHZ .SET CPUKHZ / 2 ; ADJUST FOR HALF SPEED OPERATION CPUKHZ .SET CPUKHZ * 2 ; ADJUST FOR DOUBLE SPEED OPERATION #ENDIF #ENDIF + #IF (CPUFAM == CPU_Z280) +CPUKHZ .SET CPUKHZ / 2 ; Z180 PHI IS ALWAYS 1/2 OSC + #ENDIF #ENDIF ; CPUMHZ .EQU CPUKHZ / 1000 ; CPU FREQ IN MHZ ; -TICKSPERSEC .EQU 50 +; SYSTEM PERIODIC TIMER MODE +; +#IF (BIOS == BIOS_WBW) +; +TM_NONE .EQU 0 +TM_CTC .EQU 1 +TM_TMS .EQU 2 +TM_SIMH .EQU 3 +TM_Z180 .EQU 4 +; + .ECHO "SYSTEM TIMER:" +SYSTIM .EQU TM_NONE +; + #IF (CTCENABLE & (INTMODE == 2)) + #IF (CTCTIMER) +SYSTIM .SET TM_CTC + .ECHO " CTC" + #ENDIF + #ENDIF +; + #IF (TMSENABLE & (INTMODE == 1)) + #IF (TMSTIMENABLE) +SYSTIM .SET TM_TMS + .ECHO " TMS9918" + #ENDIF + #ENDIF +; + #IF ((PLATFORM == PLT_SBC) & (INTMODE == 1)) + #IF (HTIMENABLE) +SYSTIM .SET TM_SIMH + .ECHO " SIMH" + #ENDIF + #ENDIF +; + #IF ((CPUFAM == CPU_Z180) & (INTMODE == 2)) +SYSTIM .SET TM_Z180 + .ECHO " Z180" + #ENDIF +; + #IF SYSTIM == TM_NONE + .ECHO " NONE" + #ENDIF +; + .ECHO "\n" +; +#ENDIF ; ; MEMORY BANK CONFIGURATION ; @@ -411,7 +468,7 @@ CPM_ENT .EQU CBIOS_LOC ; CPM ENTRY POINT (IN CBIOS) LDR_SIZ .EQU $0E00 MON_LOC .EQU $F000 ; LOCATION OF MONITOR FOR RUNNING SYSTEM -MON_SIZ .EQU $0E00 ; SIZE OF MONITOR BINARY IMAGE +MON_SIZ .EQU $1000 - HBX_SIZ ; SIZE OF MONITOR BINARY IMAGE MON_END .EQU MON_LOC + MON_SIZ ; END OF MONITOR BAS_LOC .EQU $0200 ; NASCOM BASIC @@ -434,7 +491,7 @@ GAM_LOC .EQU $0200 ; GAME 2048 GAM_SIZ .EQU $0900 GAM_END .EQU GAM_LOC + GAM_SIZ -USR_LOC .EQU $0200 ; USER +USR_LOC .EQU $0200 ; USER USR_SIZ .EQU $1000 USR_END .EQU USR_LOC + USR_SIZ @@ -443,9 +500,9 @@ MON_SERIAL .EQU MON_LOC + (1 * 3) ; MONITOR ENTRY (SERIAL PORT) ; ; INTERRUPT MODE 2 SLOT ASSIGNMENTS ; -#IF (INTMODE == 2) +#IF ((INTMODE == 2) | (INTMODE == 3)) - #IF (CPUFAM == CPU_Z180) + #IF ((CPUFAM == CPU_Z180) | (CPUFAM == CPU_Z280)) ; Z180-BASED SYSTEMS @@ -461,12 +518,12 @@ INT_SER1 .EQU 8 ; Z180 SERIAL 0 INT_PIO0A .EQU 9 ; ZILOG PIO 0, CHANNEL A INT_PIO0B .EQU 10 ; ZILOG PIO 0, CHANNEL B INT_PIO1A .EQU 11 ; ZILOG PIO 1, CHANNEL A -INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B +INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B INT_SIO0 .EQU 13 ; ZILOG SIO 0, CHANNEL A & B INT_SIO1 .EQU 14 ; ZILOG SIO 1, CHANNEL A & B #ELSE - + ; Z80-BASED SYSTEMS INT_CTC0A .EQU 0 ; ZILOG CTC 0, CHANNEL A @@ -474,24 +531,35 @@ INT_CTC0B .EQU 1 ; ZILOG CTC 0, CHANNEL B INT_CTC0C .EQU 2 ; ZILOG CTC 0, CHANNEL C INT_CTC0D .EQU 3 ; ZILOG CTC 0, CHANNEL D INT_SIO0 .EQU 7 ; ZILOG SIO 0, CHANNEL A & B -INT_SIO1 .EQU 8 ; ZILOG SIO 1, CHANNEL A & B +INT_SIO1 .EQU 8 ; ZILOG SIO 1, CHANNEL A & B INT_PIO0A .EQU 9 ; ZILOG PIO 0, CHANNEL A -INT_PIO0B .EQU 10 ; ZILOG PIO 0, CHANNEL B -INT_PIO1A .EQU 11 ; ZILOG PIO 1, CHANNEL A -INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B +INT_PIO0B .EQU 10 ; ZILOG PIO 0, CHANNEL B +INT_PIO1A .EQU 11 ; ZILOG PIO 1, CHANNEL A +INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B #ENDIF - + #DEFINE IVT(INTX) HB_IVT+(INTX * 4)+1 #DEFINE VEC(INTX) INTX*2 #ENDIF + +; SET DEFAULT CSIO SPEED (INTERNAL CLOCK, SLOW AS POSSIBLE) +; DIV 1280, 14KHZ @ 18MHZ CLK + +#IF (BIOS == BIOS_WBW) + #IF (CPUFAM == CPU_Z180) +Z180_CNTR_DEF .EQU $06 ; DEFAULT VALUE FOR Z180 CSIO CONFIG + #ENDIF +#ENDIF + ; ; HELPER MACROS ; #DEFINE PRTC(C) CALL PRTCH \ .DB C ; PRINT CHARACTER C TO CONSOLE - PRTC('X') #DEFINE PRTS(S) CALL PRTSTRD \ .TEXT S ; PRINT STRING S TO CONSOLE - PRTD("HELLO") #DEFINE PRTX(X) CALL PRTSTRI \ .DW X ; PRINT STRING AT ADDRESS X TO CONSOLE - PRTI(STR_HELLO) +#DEFINE DEBUG(S) CALL PRTSTRD \ .TEXT S \ .TEXT "$" ; $$$$$$ PRINT STRING S TO CONSOLE - PRTD("HELLO") - NO TRAILING $ REQUIRED ; #DEFINE XIO_PRTC(C) CALL XIO_PRTCH \ .DB C ; PRINT CHARACTER C TO CONSOLE - PRTC('X') #DEFINE XIO_PRTS(S) CALL XIO_PRTSTRD \ .DB S ; PRINT STRING S TO CONSOLE - PRTD("HELLO") diff --git a/Source/HBIOS/tastybasic.asm b/Source/HBIOS/tastybasic.asm index 243cce39..75162e67 100644 --- a/Source/HBIOS/tastybasic.asm +++ b/Source/HBIOS/tastybasic.asm @@ -1250,9 +1250,12 @@ st4: #ifndef ZEMU bye: call endchk ; ** Reboot ** - LD A,BID_BOOT ; BOOT BANK - LD HL,0 ; ADDRESS ZERO - CALL HB_BNKCALL ; DOES NOT RETURN + ;LD A,BID_BOOT ; BOOT BANK + ;LD HL,0 ; ADDRESS ZERO + ;CALL HB_BNKCALL ; DOES NOT RETURN + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_WARM ; WARM START + CALL $FFF0 ; CALL HBIOS HALT #endif new: diff --git a/Source/HBIOS/time.asm b/Source/HBIOS/time.asm index 315bde39..9bdd8c3e 100644 --- a/Source/HBIOS/time.asm +++ b/Source/HBIOS/time.asm @@ -83,7 +83,7 @@ DOW_YR .DB 0 DOW_DT .DB 0 DOW_MO .DB 0 ; -; DERIVE DOW FROM STARNDARD TIME BUFFER AT HL +; DERIVE DOW FROM STANDARD TIME BUFFER AT HL ; RETURN DOW IN A (0-6: SUN-SAT) ; TIMDOW: diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index 4759cf61..9a97ec8c 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -14,6 +14,24 @@ ; TMS DRIVER - CONSTANTS ;====================================================================== ; + +TMSCTRL1: .EQU 1 ; CONTROL BITS +TMSINTEN: .EQU 5 ; INTERRUPT ENABLE BIT + +#IF TMSTIMENABLE + .ECHO "TMS INTERRUPTS ENABLED\n" +#ENDIF + +#IF (TMSMODE == TMSMODE_RC) +TMS_DATREG .EQU $98 ; READ/WRITE DATA +TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL +TMS_PPIA .EQU 0 ; PPI PORT A +TMS_PPIB .EQU 0 ; PPI PORT B +TMS_PPIC .EQU 0 ; PPI PORT C +TMS_PPIX .EQU 0 ; PPI CONTROL PORT + +#ENDIF + #IF (TMSMODE == TMSMODE_N8) TMS_DATREG .EQU $98 ; READ/WRITE DATA @@ -50,8 +68,8 @@ TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER ; TMS_IODELAY IS USED TO ADD RECOVERY TIME TO TMS9918 ACCESSES ; IF YOU SEE SCREEN CORRUPTION, ADJUST THIS!!! ; -#IF (TMSMODE == TMSMODE_N8) -; BELOW WAS TUNED FOR N8 AT 18MHZ +#IF (CPUFAM == CPU_Z180) +; BELOW WAS TUNED FOR Z180 AT 18MHZ #DEFINE TMS_IODELAY EX (SP),HL \ EX (SP),HL ; 38 W/S #ELSE ; BELOW WAS TUNED FOR SBC AT 8MHZ @@ -62,6 +80,14 @@ TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER ; TMS DRIVER - INITIALIZATION ;====================================================================== ; +TMS_PREINIT: + ; DISABLE INTERRUPT GENERATION + LD A, (TMS_INIT9918_REG_1) + RES TMSINTEN, A ; RESET INTERRUPT ENABLE BIT + LD (TMS_INIT9918_REG_1), A + LD C, TMSCTRL1 + JP TMS_SET +; TMS_INIT: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO @@ -93,6 +119,17 @@ TMS_INIT1: #IF (TMSMODE == TMSMODE_N8) CALL PPK_INIT ; INITIALIZE KEYBOARD DRIVER #ENDIF +#IF (INTMODE == 1 & TMSTIMENABLE) + ; ADD IM1 INT CALL LIST ENTRY + LD HL, TMS_TSTINT ; GET INT VECTOR + CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST + + LD A, (TMS_INIT9918_REG_1) + SET TMSINTEN, A ; SET INTERRUPT ENABLE BIT + LD (TMS_INIT9918_REG_1), A + LD C, TMSCTRL1 + CALL TMS_SET +#ENDIF ; ; ADD OURSELVES TO VDA DISPATCH TABLE LD BC,TMS_FNTBL ; BC := FUNCTION TABLE ADDRESS @@ -107,7 +144,13 @@ TMS_INIT1: ; XOR A ; SIGNAL SUCCESS RET -; + +#IF TMSTIMENABLE + ; DISABLE INTERRUPT +TMS_INT_DIS: + +#ENDIF +; ;====================================================================== ; TMS DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS ;====================================================================== @@ -136,6 +179,7 @@ TMS_FNTBL: #ENDIF #IF (($ - TMS_FNTBL) != (VDA_FNCNT * 2)) .ECHO "*** INVALID TMS FUNCTION TABLE ***\n" + !!!!! #ENDIF TMS_VDAINI: @@ -169,19 +213,24 @@ TMS_VDARES1: ; ENTRY POINT TO AVOID TMS_Z180IO RECURSION DEC A LD (TMS_CURSAV),A CALL TMS_SETCUR ; SET CURSOR - + XOR A ; SIGNAL SUCCESS RET - + TMS_VDADEV: LD D,VDADEV_TMS ; D := DEVICE TYPE LD E,0 ; E := PHYSICAL UNIT IS ALWAYS ZERO + LD H,TMSMODE ; H := MODE + LD L,TMS_DATREG ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET - + TMS_VDASCS: - CALL PANIC ; NOT IMPLEMENTED (YET) - + CALL SYSCHK ; NOT IMPLEMENTED (YET) + LD A,ERR_NOTIMPL + OR A + RET + TMS_VDASCP: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO @@ -191,15 +240,15 @@ TMS_VDASCP: CALL TMS_SETCUR XOR A ; SIGNAL SUCCESS RET - + TMS_VDASAT: XOR A ; NOT POSSIBLE, JUST SIGNAL SUCCESS RET - + TMS_VDASCO: XOR A ; NOT POSSIBLE, JUST SIGNAL SUCCESS RET - + TMS_VDAWRC: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO @@ -210,7 +259,7 @@ TMS_VDAWRC: CALL TMS_SETCUR XOR A ; SIGNAL SUCCESS RET - + TMS_VDAFIL: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO @@ -238,7 +287,7 @@ TMS_VDACPY: CALL TMS_SETCUR XOR A RET - + TMS_VDASCR: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO @@ -293,7 +342,7 @@ TMS_SET: OUT (TMS_CMDREG),A ; WRITE IT TMS_IODELAY LD A,C ; GET THE DESIRED REGISTER - OR $80 ; SET BIT 7 + OR $80 ; SET BIT 7 OUT (TMS_CMDREG),A ; SELECT THE DESIRED REGISTER TMS_IODELAY RET @@ -397,7 +446,7 @@ TMS_LOADFONT: LD (TMS_STACK),SP ; SAVE STACK LD HL,(TMS_STACK) ; AND SHIFT IT LD DE,$2000 ; DOWN 4KB TO - CCF ; CREATE A + CCF ; CREATE A SBC HL,DE ; DECOMPRESSION BUFFER LD SP,HL ; HL POINTS TO BUFFER EX DE,HL ; START OF STACK BUFFER @@ -596,7 +645,7 @@ TMS_SCROLL1: INC DE DJNZ TMS_SCROLL1 POP HL ; RECOVER THE DESTINATION -; +; ; WRITE THE BUFFERED LINE TO CURRENT DESTINATION CALL TMS_WR ; SET UP TO WRITE LD DE,TMS_BUF @@ -732,7 +781,7 @@ TMS_Z180IO: OUT0 (Z180_DCNTL),A ; IMPLEMENT IT POP AF ; RESTORE AF ; BACK TO CALLER -TMS_Z180IOR .EQU $+1 +TMS_Z180IOR .EQU $+1 JP $0000 ; BACK TO CALLER ; TMS_Z180IOX: @@ -744,6 +793,20 @@ TMS_Z180IOX: RET ; DONE ; #ENDIF + +#IF (INTMODE == 1 & TMSTIMENABLE) +TMS_TSTINT: + IN A, (TMS_CMDREG) ; TEST FOR INT FLAG + AND $80 + JR NZ, TMS_INTHNDL + AND $00 ; RETURN Z - NOT HANDLED + RET + +TMS_INTHNDL: + CALL HB_TIMINT ; RETURN NZ - HANDLED + OR $FF + RET +#ENDIF ; ;================================================================================================== ; TMS DRIVER - DATA @@ -752,6 +815,22 @@ TMS_Z180IOX: TMS_POS .DW 0 ; CURRENT DISPLAY POSITION TMS_CURSAV .DB 0 ; SAVES ORIGINAL CHARACTER UNDER CURSOR TMS_BUF .FILL 256,0 ; COPY BUFFER + +; +;================================================================================================== +; TMS DRIVER - INSTANCE DATA +;================================================================================================== +; + +TMS_IDAT: + .DB TMS_PPIA + .DB TMS_PPIB + .DB TMS_PPIC + .DB TMS_PPIX + +TMS_PORTS: + .DB TMS_DATREG + .DB TMS_CMDREG ; ;================================================================================================== ; TMS DRIVER - TMS9918 REGISTER INITIALIZATION @@ -797,6 +876,7 @@ TMS_BUF .FILL 256,0 ; COPY BUFFER ; TMS_INIT9918: .DB $00 ; REG 0 - NO EXTERNAL VID +TMS_INIT9918_REG_1: .DB $50 ; REG 1 - ENABLE SCREEN, SET MODE 1 .DB $00 ; REG 2 - PATTERN NAME TABLE := 0 .DB $00 ; REG 3 - NO COLOR TABLE @@ -807,16 +887,11 @@ TMS_INIT9918: ; TMS_INIT9918LEN .EQU $ - TMS_INIT9918 ; +; #IF (CPUFAM == CPU_Z180) TMS_DCNTL .DB $00 ; SAVE Z180 DCNTL AS NEEDED #ENDIF -; -;================================================================================================== -; TMS DRIVER - INSTANCE DATA -;================================================================================================== -; -TMS_IDAT: - .DB TMS_PPIA - .DB TMS_PPIB - .DB TMS_PPIC - .DB TMS_PPIX + + .ECHO "TMS instance data occupies " + .ECHO $ - TMS_IDAT + .ECHO " bytes\n" diff --git a/Source/HBIOS/uart.asm b/Source/HBIOS/uart.asm index 75466d50..52ecd2cf 100644 --- a/Source/HBIOS/uart.asm +++ b/Source/HBIOS/uart.asm @@ -230,11 +230,23 @@ UART_INITDEV1: LD A,C UART_OUTP(UART_DLL) ; SET DIVISOR (LS) ; - ; SETUP FCR (DLAB MUST STILL BE ON FOR ACCESS TO BIT 5) - LD A,%00100111 ; FIFO ENABLE & RESET, 64 BYTE FIFO ENABLE ON 750+ + ; FOR 750+, WE ENABLE THE 64-BYTE FIFO + ; DLAB MUST STILL BE ON FOR ACCESS TO BIT 5 + ; WE DO *NOT* ENABLE ANY OTHER FCR BITS HERE + ; BEACAUSE IT WILL SCREW UP THE 2552!!! + LD A,%00100000 UART_OUTP(UART_FCR) ; DO IT ; - ; SETUP LCR FROM SECOND CONFIG BYTE (DLAB IS CLEARED) + XOR A ; DLAB OFF NOW + UART_OUTP(UART_LCR) ; DO IT +; + ; SETUP FCR, BIT 5 IS KEPT ON EVEN THOUGH IT IS PROBABLY + ; IRRELEVANT BECAUSE IT ONLY APPLIES TO 750 AND DLAB IS + ; NOW OFF, BUT DOESN'T HURT. + LD A,%00100111 ; FIFO ENABLE & RESET + UART_OUTP(UART_FCR) ; DO IT +; + ; SETUP LCR FROM SECOND CONFIG BYTE LD A,(IY + 4) ; GET CONFIG BYTE AND ~$C0 ; ISOLATE PARITY, STOP/DATA BITS UART_OUTP(UART_LCR) ; SAVE IT @@ -327,6 +339,8 @@ UART_DEVICE: LD D,CIODEV_UART ; D := DEVICE TYPE LD E,(IY) ; E := PHYSICAL UNIT LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+2) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; @@ -364,8 +378,9 @@ UART_DETECT: CP $5A ; SPR STILL THERE? JR NZ,UART_DETECT1 ; NOPE, HIDDEN, MUST BE 16650/850 ; - ; RESET LCR TO DEFAULT - LD A,$80 ; DLAB BIT ON + ; RESET LCR TO DEFAULT (DLAB OFF) + ;LD A,$80 ; DLAB BIT ON + XOR A ; DLAB BIT OFF UART_OUTP(UART_LCR) ; RESET LCR ; ; TEST FCR TO ISOLATE 16450/550/550A @@ -381,6 +396,9 @@ UART_DETECT: JR UART_DETECT_16750 ; ONLY THING LEFT IS 16750 ; UART_DETECT1: ; PICK BETWEEN 16650/850 + ; RESET LCR TO DEFAULT (DLAB OFF) + XOR A ; DLAB BIT OFF + UART_OUTP(UART_LCR) ; RESET LCR ; NOT SURE HOW TO DIFFERENTIATE 16650 FROM 16850 YET JR UART_DETECT_16650 ; ASSUME 16650 RET diff --git a/Source/HBIOS/uf.asm b/Source/HBIOS/uf.asm index efc3d9b3..b67c15ab 100644 --- a/Source/HBIOS/uf.asm +++ b/Source/HBIOS/uf.asm @@ -154,6 +154,8 @@ UF_DEVICE: XOR A ; SIGNAL SUCCESS LD E,A ; E := PHYSICAL UNIT, ALWAYS 0 LD C,A ; C := DEVICE TYPE, 0x00 IS RS-232 + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,UFBASE ; L := BASE I/O ADDRESS RET ; ; USB-FIFO DETECTION ROUTINE diff --git a/Source/HBIOS/unlzsa2s.asm b/Source/HBIOS/unlzsa2s.asm index 5709fc07..02de89cb 100644 --- a/Source/HBIOS/unlzsa2s.asm +++ b/Source/HBIOS/unlzsa2s.asm @@ -82,10 +82,12 @@ #DEFCONT \ lddr #ENDIF + + .ECHO "UNLZSA2 for " #IFDEF HD64180 - .ECHO "HD64180 " + .ECHO "HD64180" #DEFINE LD_IX_DE \ #DEFCONT \ ld ixl,e \ ld ixh,d @@ -95,7 +97,7 @@ #ELSE - .ECHO "Z80 " + .ECHO "Z80" #DEFINE LD_IX_DE \ #DEFCONT \ push de \ pop ix @@ -104,6 +106,8 @@ #DEFCONT \ push ix \ pop de #ENDIF + + .ECHO ".\n" DLZSA2: xor a \ ld b,a \ ex af,af' \ jr ReadToken diff --git a/Source/HBIOS/updater.asm b/Source/HBIOS/updater.asm new file mode 100644 index 00000000..f53bd3ab --- /dev/null +++ b/Source/HBIOS/updater.asm @@ -0,0 +1,1231 @@ +;***************************************************************************** +; ROMWBW XMODEM FLASH UPDATER +; +; PROVIDES THE CAPABILTY TO UPDATE ROMWBW FROM THE SBC BOOT LOADER USING +; AN XMODEM FILE TRANSFER. +; +; TO INSTALL, SAVE THIS FILE AS USRROM.ASM IN \RomWBW\Source\HBIOS +; AND REBUILD AND INSTALL THE NEW ROM VERSION. +; +; THE UPDATER CAN THEN BE ACCESSED USING THE "U" OPTION IN THE SBC BOOT LOADER. +; +; OPTION (C) AND (S) - CONSOLE AND SERIAL DEVICE +; +; BY DEFAULT THE UPDATER IS SET TO USE THE CURRENT CONSOLE DEVICE FOR +; DISPLAY OUTPUT AND FILES TRANSFER. IF YOU USE A DIFFERENT SERIAL DEVICE FOR +; THE FILE TRANSFER, PROGRESS INFORMATION WILL BE DISPLAYED. +; +; OPTION (V) - WRITE VERIFY +; +; BY DEFAULT EACH FLASH SECTOR WILL BE VERIFIED AFTER BEING WRITTEN. SLIGHT +; PERFORMANCE IMPROVEMENTS CAN BE GAINED IF TURNED OFF AND COULD BE USED IF +; YOU ARE EXPERIENCING RELIABLE TRANSFERS AND FLASHING. +; +; OPTION (R) - REBOOT +; EXECUTE A COLD REBOOT. THIS SHOULD BE DONE AFTER A SUCCESSFUL UPDATE. IF +; YOU PERFORM A COLD REBOOT AFTER A FAILED UPDATE THEN IT IS LIKELY THAT +; YOUR SYSTEM WILL BE UNUSABLE AND REMOVING AND REPROGRAMMING THE FLASH +; WILL BE REQUIRED. +; +; OPTION (U) - BEGIN UPDATE +; WILL BEGIN THE UPDATE PROCESS. THE UPDATER WILL EXPECT TO START RECEIVING +; AN XMODEM FILE ON THE SERIAL DEVICE UNIT. +; +; XMODEM SENDS THE FILE IN PACKETS OF 128 BYTES. THE UPDATER WILL CACHE 32 +; PACKETS WHICH IS 1 FLASH SECTOR AND THEN WRITE THAT SECTOR TO THE +; FLASH DEVICE. +; +; IF USING SEPARATE CONSOLE, BANK AND SECTOR PROGESS INFORMATION WILL SHOWN +; +; BANK 00 S00 S01 S02 S03 S04 S05 S06 S06 S07 +; BANK 01 S00 S01 S02 S03 S04 S05 S06 S06 S07 +; BANK 02 S00 S01 S02 S03 S04 S05 S06 S06 S07 etc +; +; THE XMODEM FILE TRANSFER PROTOCOL DOES NOT PROVIDE ANY FILENAME OR SIZE +; INFORMATION FOR THE TRANSFER SO THE UPDATER DOES NOT PERFORM ANY CHECKS +; ON THE FILE SUITABILITY. +; +; THE UPDATER EXPECTS THE FILE SIZE TO BE A MULTIPLE OF 4 KILOBYTES AND +; WILL WRITE ALL DATA RECEIVED TO THE FLASH DEVICE. A SYSTEM UPDATE +; FILE (128KB .IMG) OR COMPLETE ROM CAN BE RECEIVED AND WRITTEN (512KB OR +; 1024KB .ROM) +; +; IF THE UPDATE FAILS IT IS RECOMMENDED THAT YOU RETRY BEFORE REBOOTING OR +; EXITING TO THE SBC BOOT LOADER AS YOUR MACHINE MAY NOT BE BOOTABLE. +; +; OPTION (X) - EXIT TO THE SBC BOOT LOADER. THE SBC IS RELOADED FROM ROM AND +; EXECUTED. AFTER A SUCCESSFUL UPDATE A REBOOT SHOULD BE PERFORMED. HOWEVER, +; IN THE CASE OF A FAILED UPDATE THIS OPTION COULD BE USED TO ATTEMPT TO +; LOAD CP/M AND PERFORM THE NORMAL XMODEM / FLASH PROCESS TO RECOVER. +; +; OPTION (D) - DUPLICATE FLASH #1 TO FLASH #2 WILL MAKE A COPY OF FLASH #1 +; ONTO FLASH #2. THE PURPOSE OF THIS IS TO ENABLE MAKING A BACKUP COPY OF +; THE CURRENT FLASH. +; +; OPTION (1) AND (2) - CALCULATE AND DISPLAY CRC32 OF 1ST OR 2ND 512K ROM. +; +; OPTION (H) - DEBUG OPTION - SWITCH ON CPU CLOCK DIVIDER ON SBC-V2-004+ +; OPTION (T) - DEBUG OPTION - TEST TIMER FOR 32S, 16S, 8S, 4S, 2S & 1S +; +; +; V.DEV 18/1/2021 PHIL SUMMERS, DIFFICULTYLEVELHIGH@GMAIL.COM +; b1ackmai1er ON RETROBREWCOMPUTERS.ORG +; +; +; NOTES: +; TESTED WITH TERATERM XMODEM. +; PARTIAL WRITES CAN BE COMPLETED WITH 39SF040 CHIPS +; OTHER CHIPS REQUIRE ENTIRE FLASH TO BE ERASED BEFORE BEFORE BEING WRITTEN. +; SBC V2-005 MEGAFLASH REQUIRED FOR 1MB FLASH SUPPORT. +; ASSUMES BOTH CHIPS ARE SAME TYPE +; FAILURE HANDLING HAS NOT BEEN TESTED. +; TIMING BROADLY CALIBRATED ON A Z80 SBC-V2 +; UNABIOS NOT SUPPORTED +; +; TERATERM: +; +; MACROS CAN BE USED TO AUTOMATE SENDING ROM UPDATES OR ROMS IMAGES. +; TRANSMISSION STARTUP IS MORE RELIABLE WHEN THE CHECKSUM OPTION (1) IS SPECIFIED +; +; EXAMPLE MACRO FILE TO SEND *.UPD FILE, SELECT CHECKSUM MODE AND DISPLAY CRC32 +; +; ;XMODEM send, checksum, display CRC32 +; xmodemsend '\\DESKTOP-FI43VI2\Users\Phillip\Documents\GitHub\RomWBW\Binary\SBC_std_cust.upd' 1 +; crc32file crc '\\DESKTOP-FI43VI2\Users\Phillip\Documents\GitHub\RomWBW\Binary\SBC_std_cust.rom' +; sprintf '0x%08X' crc +; messagebox inputstr 'CRC32' +; +; MAXIMUM SERIAL SPEED LIMITATIONS: +; +; SBC-V2 UART NO FLOW CONTROL 2MHZ | 9600 +; SBC-V2 UART NO FLOW CONTROL 4MHZ | 19200 +; SBC-V2 UART NO FLOW CONTROL 5MHZ | 19200 +; SBC-V2 UART NO FLOW CONTROL 8MHZ | 38400 +; SBC-V2 UART NO FLOW CONTROL 10MHZ | 38400 +; SBC-V2 USB-FIFO 2MHZ+ | N/A +; SBC-MK4 ASCI NO FLOW CONTROL 18.432MHZ | 9600 +; SBC-MK4 ASCI WITH FLOW CONTROL 18.432MHZ | 38400 +; +; ACKNOWLEDGEMENTS: +; +; XR - Xmodem Receive for Z80 CP/M 2.2 using CON: +; Copyright 2017 Mats Engstrom, SmallRoomLabs +; Licensed under the MIT license +; https://github.com/SmallRoomLabs/xmodem80/blob/master/XR.Z80 +; +; md.asm - ROMWBW memory disk driver +; https://github.com/wwarthen/RomWBW/blob/master/Source/HBIOS/md.asm +; +; CRC32 - J.G. HARSTON - mdfs.net/Info/Comp/Comms/CRC32.htm +; +;***************************************************************************** +; +#INCLUDE "std.asm" +; +HBX_BNKSEL .EQU $FE2B +; +#DEFINE HB_DI DI +#DEFINE HB_EI EI +; +XFUDBG .EQU 0 +; + .ORG USR_LOC +; +; ASCII codes +; +LF: .EQU 'J'-40h ; ^J LF +CR: .EQU 'M'-40h ; ^M CR/ENTER +SOH: .EQU 'A'-40h ; ^A CTRL-A +EOT: .EQU 'D'-40h ; ^D = End of Transmission +ACK: .EQU 'F'-40h ; ^F = Positive Acknowledgement +NAK: .EQU 'U'-40h ; ^U = Negative Acknowledgement +CAN: .EQU 'X'-40h ; ^X = Cancel +BSPC: .EQU 'H'-40h ; ^H = Backspace +; +; Start of code +; + LD (oldSP),SP ; SETUP STACK BELOW HBIOS + LD SP,HBX_LOC-MD_CSIZ ; ALLOW FOR RELOCATABLE CODE AREA +; + LD HL,MD_FSTART ; COPY FLASH + LD DE,HBX_LOC-MD_CSIZ ; ROUTINES TO + LD BC,MD_CSIZ ; HIGH MEMORY + LDIR +; + LD BC,$F8F2 ; LOOKUP + RST 08 ; CURRENT + LD B,$FA ; CONSOLE + LD HL,$112 ; DEVICE + RST 08 ; TO USE AS + LD A,E ; DEFAULT + LD (CONDEV),A +; + LD BC,$F8F2 ; LOOKUP + RST 08 ; CURRENT + LD B,$FA ; SERIAL + LD HL,$110 ; DEVICE + RST 08 ; TO USE AS + LD A,E ; DEFAULT + LD (SERDEV),A +; + LD HL,msgHeader ; PRINT + CALL PRTSTR0 ; GREETING +; +RESTART: + LD DE,$0000 ; SET UP START + LD (MD_FBAS),DE ; BANK AND SECTOR + + LD HL,MD_FIDEN ; IDENTIFY CHIP + CALL MD_FNCALL ; AT THIS BANK/SECTOR + + LD HL,$B7BF ; IS IT A 39SF040 + XOR A + SBC HL,BC + LD A,0 + JR Z,CHPFND ; YES IT IS ... +; + LD HL,$A401 ; IS IT A 29F040 + XOR A + SBC HL,BC + LD A,1 + JR Z,CHPFND ; YES IT IS ... +; + LD HL,$131F ; IS IT AN AT49F040 + XOR A + SBC HL,BC + LD A,2 + JR Z,CHPFND ; YES IT IS +; + LD HL,$A41F ; IS IT AN AT29C040 + XOR A + SBC HL,BC + LD A,3 + JR Z,CHPFND ; YES IT IS +; + LD HL,$E220 ; IS IT AN M29F040 + XOR A + SBC HL,BC + LD A,4 + JR Z,CHPFND ; YES IT IS +; + LD HL,$A4C2 ; IS IT AN MX29F040 + SBC HL,BC + LD A,5 +; + JP NZ,FAILBC ; SUPPORTED CHIP NOT FOUND +; +CHPFND: LD (ERATYP),A ; SAVE ERASE TYPE + + LD BC,$F8F0 ; GET CPU SPEED + RST 08 ; AND MULTIPLY + LD A,L ; BY 4 + ADD A,A ; TO CREATE + ADD A,A ; TIMEOUT DELAY + LD (TmoFct),A ; FACTOR +; +MENULP: LD DE,$0000 ; ENSURE WE ARE STARTING + LD (MD_FBAS),DE ; AT BANK 0 SECTOR 0 + + LD HL,ERATYP ; RESET THE ERASE + RES 7,(HL) ; SKIP FLAG +; + CALL MENU ; DISPLAY MENU + CALL GETINP ; GET SELECTION +; + CP 'U' ; BEGIN + JR Z,BEGUPD ; TRANSFER +; + CP 'V' ; CHECK FOR + JP Z,OPTIONV ; VERIFY TOGGLE +; + CP 'X' ; CHECK FOR + JP Z,FAILUX ; USER EXIT +; + CP 'R' ; CHECK FOR + JP Z,REBOOT ; COLD REBOOT REQUEST +; + CP 'C' ; CHECK FOR + JP Z,OPTIONC ; CONSOLE CHANGE +; + CP 'S' ; CHECK FOR + JP Z,OPTIONS ; SERIAL CHANGE +; + CP 'D' ; DUPLICATE + JP Z,OPTIOND ; FLASH +; + CP '1' ; CALCULATE + JP Z,OPTION1 ; CRC 512K FLASH +; + CP '2' ; CALCULATE + JP Z,OPTION2 ; CRC 1024K FLASH +; +#IF (XFUDBG) + CP '3' ; CALCULATE + JP Z,OPTION3 ; CRC FLASH #2 +; + CP 'T' ; TEST TIMEOUT + JP Z,OPTIONT ; LOOP +; + CP 'H' ; HALF + JP Z,OPTIONH ; SPEED SWITCH +; + CP 'F' ; DEBUG + JP Z,OPTIONF ; DUMP +; + CP 'E' ; ERASE + JP Z,OPTIONE ; CHIP #1 +; + CP 'Z' ; ERASE + JP Z,OPTIONR ; CHIP #2 +#ENDIF +; + JR MENULP +; +BEGUPD: CALL SERST ; EMPTY SERIAL BUFFER + OR A ; SO WE HAVE A CLEAN + JR Z,SERCLR ; START ON TRANSFER + CALL SERIN + JR BEGUPD +; +SERCLR: LD HL,msgInstr ; PROVIDE + CALL PRTSTR0 ; INSTRUCTION +; + LD A,(SERDEV) ; IF CONSOLE AND SERIAL + LD HL,CONDEV ; DEVICE ARE THE SAME, + SUB (HL) ; BLOCK ALL TEXT + LD (BLKCOUT),A ; OUTPUT DURING TRANSFER +; + LD A,1 ; THE FIRST PACKET IS NUMBER 1 + LD (pktNo),A + LD A,255-1 ; ALSO STORE THE 1-COMPLEMENT OF IT + LD (pktNo1c),A +; + LD DE,sector4k ; POINT TO START OF SECTOR TO WRITE +; +GetNewPacket: + LD HL,retrycnt ; WE RETRY 20 TIMES BEFORE GIVING UP + LD (HL),20 +; +NPloop: LD B,6 ; 6 SECONDS OF TIMEOUT BEFORE EACH NEW BLOCK + CALL GetCharTmo + JP NC,NotPacketTimeout +; + DEC (HL) ; REACHED MAX NUMBER OF RETRIES? + JP Z,FAILRT ; YES, PRINT MESSAGE AND EXIT +; + LD C,NAK ; SEND A NAK TO THE UPLOADER + CALL SEROUT + JR NPloop +; +NotPacketTimeout: + CP EOT ; DID UPLOADER SAY WE'RE FINISHED? + JP Z,Done ; YES, THEN WE'RE DONE + CP CAN ; UPLOADER WANTS TO FAIL TRANSFER? + JP Z,FAILCN ; YES, THEN WE'RE ALSO DONE + CP SOH ; DID WE GET A START-OF-NEW-PACKET? + JR NZ,NPloop ; NO, GO BACK AND TRY AGAIN +; +#IF (XFUDBG) + LD HL,packet ; SAVE THE RECEIVED CHAR INTO THE... + LD (HL),A ; ...PACKET BUFFER AND... + INC HL ; ...POINT TO THE NEXT LOCATION +#ELSE + LD HL,packet+1 ; SKIP SAVING +#ENDIF +; + CALL GetCharTmo1 ; GET CHARACTER + LD (HL),A ; SHOULD BE PACKET NUMBER + INC HL + JR C,FAILTO +; + CALL GetCharTmo1 ; GET CHARACTER + LD (HL),A ; SHOULD BE PACKET NUMBER + INC HL ; COMPLEMENT + JR C,FAILTO +; + LD C,0 ; GET 128 MORE CHARACTERS FOR A FULL PACKET +GetRestOfPacket: ; C=0=256 TO ALLOW FOR DOUBLE DECREMENT + CALL GetCharTmo1 ; GET CHARACTER + JR C,FAILTO +; + LD (HL),A ; SAVE THE RECEIVED CHAR INTO THE + LDI ; PACKET BUFFER AND FLASH SECTOR BUFFER +; + DEC C ; C GETS DECREMENTED TWICE EACH LOOP. +; + JP NZ,GetRestOfPacket +; + CALL GetCharTmo1 ; GET CHARACTER + LD (HL),A ; SHOULD BE CHECKSUM + JR C,FAILTO +; + LD HL,packet+3 ; CALCULATE CHECKSUM FROM 128 BYTES OF DATA + LD B,128 + XOR A +csloop: ADD A,(HL) ; JUST ADD UP THE BYTES + INC HL + DJNZ csloop +; + XOR (HL) ; HL POINTS TO THE RECEIVED CHECKSUM SO + JR NZ,FAILCS ; BY XORING IT TO OUR SUM WE CHECK FOR EQUALITY +; + LD HL,(pktNo) ; CHECK + LD BC,(packet+1) ; AGREEMENT +; XOR A ; PACKET + SBC HL,BC ; NUMBERS + JR NZ,FAILPN +; + LD A,C ; HAVE WE RECEIVED A BLOCK OF 32 + DEC A ; XMODEM PACKETS? + AND %00011111 ; IF YES THEN WERE WE + CP %00011111 ; HAVE ENOUGH TO + LD A,H ; WRITE A FLASH SECTOR + CALL Z,WSEC ; ASSUME FLASH SUCCESSFUL + OR A ; EXIT IF WE GOT A + JR NZ,FAILWF ; WRITE VERIFICATION ERROR +; + LD HL,pktNo ; UPDATE THE PACKET COUNTERS + INC (HL) + INC HL + DEC (HL) +; + LD C,ACK ; TELL UPLOADER THAT WE'RE HAPPY WITH WITH + CALL SEROUT ; PACKET AND GO BACK AND FETCH SOME MORE +; + JP GetNewPacket +; +FAILTO: LD HL,msgTimout ; TIMEOUT WAITING + JR ERRRX ; FOR CHARACTER +; +COUTON: LD A,$FF ; TURN ON + LD (BLKCOUT),A ; OUTPUT + RET +; +Done: LD C,ACK ; TELL UPLOADER + CALL SEROUT ; WE'RE DONE +Done1: LD HL,msgSuccess ; BACK TO + JR MSGRS ; MENU +; +FAILWF: LD HL,msgFailWrt ; FLASH + JR MSGRS ; VERIFY FAIL +; +FAILRT: LD HL,msgRetry ; RETRY + JR ERRRX ; TIMEOUT FAIL +; +FAILCS: LD HL,msgChkSum ; CHECKSUM + JR ERRRX ; ERROR +; +FAILPN: LD HL,msgPacErr ; PACKET + JR ERRRX ; NUMBER ERROR +; +FAILCN: LD HL,msgCancel ; TRANSMISSION + JR ERRRX ; FAILURE +; +FAILUX: LD HL,msgUserEx ; USER + JR Die ; EXIT +; +FAILBC: LD HL,msgUnsupC ; UNSUPPORTED + JR Die ; FLASH CHIP +; +ERRRX: CALL COUTON ; TURN ON OUTPUT + CALL PRTSTR0 ; DISPLAY TRANSMISSION + LD HL,msgFailure ; RECEIPT ERROR + CALL PRTSTR0 + JP RESTART +; +MSGRS: CALL COUTON ; TURN ON OUTPUT + CALL PRTSTR0 ; DISPLAY + JP RESTART ; MESSAGE +; +REBOOT: LD HL,msgReboot ; REBOOT MESSAGE + CALL PRTSTR0 + LD C,BF_SYSRES_COLD ; COLD RESTART + JR Die1 +; +Die: CALL COUTON ; TURN ON OUTPUT + CALL PRTSTR0 ; Prints message and exits from program + LD C,BF_SYSRES_WARM ; WARM START +Die1: LD B,BF_SYSRESET ; SYSTEM RESTART + LD SP,(oldSP) + CALL $FFF0 ; CALL HBIOS + RET + +WSEC: CALL DISPROG ; DISPLAY PROGRESS +; +WSEC1: LD A,(ERATYP) ; SECTOR + OR A ; ERASE? + JP Z,WSEC4 +; + JP M,WSEC3 ; SKIP ERASE? +; + LD HL,MD_FERAC ; SETUP CHIP ERASE + SET 7,A ; SET FLAG SO + LD (ERATYP),A ; WE DONT ERASE AGAIN + JR WSEC2 +; +WSEC4: LD HL,MD_FERAS ; SET ERASE SECTOR +WSEC2: CALL MD_FNCALL ; ERASE CHIP OR SECTOR +; +WSEC3: LD IX,sector4k ; WRITE THIS + LD HL,MD_FWRIT ; BANK / SECTOR + CALL MD_FNCALL +; + LD A,(WRTVER) ; VERIFY + OR A ; WRITE IF + JR Z,NOVER ; OPTION SET +; + LD IX,sector4k ; VERIFY + LD HL,MD_FVERI ; WRITE + CALL MD_FNCALL + LD (VERRES),A ; SAVE STATUS +; +NOVER: LD DE,sector4k ; POINT BACK TO START OF 4K BUFFER +; + LD HL,MD_FBAS + LD A,(HL) ; DID WE JUST + SUB $70 ; DO LAST + JR NZ,NXTS2 ; SECTOR +; + LD (HL),A ; RESET SECTOR TO 0 + INC HL + INC (HL) ; NEXT BANK +; + CP $10 ; IF WE ARE AT THE + JR NZ,NXTS3 ; START OF A NEW + LD HL,ERATYP ; CHIP THEN ALLOW + RES 7,(HL) ; CHIP ERASE BY + JR NXTS3 ; RESETTING FLAG +; +NXTS2: LD A,$10 ; NEXT SECTOR + ADD A,(HL) ; EACH SECTOR IS $1000 + LD (HL),A ; SO WE JUST INCREASE HIGH BYTE +; +NXTS3: LD A,(VERRES) ; EXIT WITH STATUS + RET +; +DISPROG:LD A,(BLKCOUT) ; SKIP OUTPUT + OR A ; IF OUTPUT + RET Z ; BLOCKED +; + LD A,(MD_SECT) ; IF SECTOR IS 0 + OR A ; THEN DISPLAY + JR NZ,DISP1 ; BANK # PREFIX + LD HL,msgBank + CALL PRTSTR0 + LD A,(MD_BANK) + CALL PRTHEXB +; +DISP1: LD C,' ' ; DISPLAY + CALL CONOUT ; CURRENT + LD C,'S' ; SECTOR + CALL CONOUT + LD A,(MD_SECT) + RRCA + RRCA + RRCA + RRCA + CALL PRTHEXB + RET +; +; WAITS FOR UP TO B SECONDS FOR A CHARACTER TO BECOME AVAILABLE AND +; RETURNS IT IN A WITHOUT ECHO AND CARRY CLEAR. IF TIMEOUT THEN CARRY +; IT SET. +; +; 4MHZ 20 SECONDS TmoFct = 16 +; 10MHZ 20 SECONDS TmoFct = 39 +; +GetCharTmo1: + LD B,1 ; WAIT 1 SECOND FOR SERIAL INPUT +GetCharTmo: + CALL SERST ; IF THERE IS A + OR A ; CHARACTER AVAILABLE + JR NZ,GotChrX ; EXIT NOW OTHERWISE POLL +GCtmoa: PUSH BC + LD BC,255 ; C=CONSTANT (255) FOR INNER TIMING LOOP +TmoFct: .EQU $-1 ; B=SPEED FACTOR WHICH GETS UPDATED AT START +GCtmob: PUSH BC + LD B,C +GCtmoc: PUSH BC + CALL SERST + OR A ; A CHAR AVAILABLE? + JR NZ,GotChar ; YES, GET OUT OF LOOP + POP BC + DJNZ GCtmoc + POP BC + DJNZ GCtmob + POP BC + DJNZ GetCharTmo + SCF ; SET CARRY SIGNALS TIMEOUT + RET +; +GotChar:POP BC + POP BC + POP BC +GotChrX:CALL SERIN + OR A ; CLEAR CARRY SIGNALS SUCCESS + RET +; +GETINP: CALL CONIN ; GET A CHARACTER + LD C,A ; RETURN SEQUENCE + CALL CONOUT ; CONVERT TO UPPERCASE + LD C,BSPC ; RETURN CHARACTER IN A + CALL CONOUT + LD B,A + CP BSPC + JR Z,GETINP +GETINP2:CALL CONIN + CP BSPC + JR Z,GETINP + CP CR + JR NZ,GETINP2 + LD A,B + LD C,A + CALL CONOUT + CP 'a' ; BELOW 'A'? + JR C,GETINP3 ; IF SO, NOTHING TO DO + CP 'z'+1 ; ABOVE 'Z'? + JR NC,GETINP3 ; IF SO, NOTHING TO DO + AND ~$20 ; CONVERT CHARACTER TO LOWER +GETINP3:RET +; +PRTSTR0:LD A,(HL) ; PRINT MESSAGE POINTED TOP HL UNTIL 0 + OR A ; CHECK IF GOT ZERO? + RET Z ; IF ZERO RETURN TO CALLER + LD C,A + CALL CONOUT ; ELSE PRINT THE CHARACTER + INC HL + JP PRTSTR0 +; +MENU: CALL COUTON + LD HL,msgConsole ; DISPLAY + CALL PRTSTR0 ; CONSOLE + LD A,(CONDEV) ; DEVICE + ADD A,'0' + LD C,A + CALL CONOUT +; + LD HL,msgIODevice ; DISPLAY + CALL PRTSTR0 ; SERIAL + LD A,(SERDEV) ; DEVICE + ADD A,'0' + LD C,A + CALL CONOUT +; + LD HL,msgWriteV ; DISPLAY + CALL PRTSTR0 ; VERIFY + LD A,(WRTVER) ; OPTION + OR A + LD HL,msgYES + JR NZ,MENU1 + LD HL,msgNO +MENU1: CALL PRTSTR0 +; + LD HL,msgBegin ; DISPLAY OTHER + CALL PRTSTR0 ; MENU OPTIONS + RET +; +OPTIOND:CALL COUTON ; TURN ON OUTPUT +; + LD HL,msgConfirm ; CONFIRM + CALL PRTSTR0 ; OK + CALL GETINP ; TO + CP 'Y' ; PROCEED + JP NZ,MENULP +DUPL: LD HL,msgCopying + CALL PRTSTR0 +; + LD A,(ERATYP) ; CHECK IF WE + OR A ; NEED TO DO + JR Z,NOERA1 ; A CHIP ERASE +; + LD HL,$1000 + LD (MD_FBAS),HL + LD HL,MD_FERAC ; ERASE + CALL MD_FNCALL ; CHIP #2 + OR A + JP FAILWF +; +NOERA1: LD B,16 ; LOOP THROUGH 16 BANKS +; + XOR A ; START AT + LD (MD_BANK),A ; BANK 0 +; +NXTB: PUSH BC +; + XOR A ; START AT + LD (MD_SECT),A ; SECTOR 0 +; + LD B,8 ; LOOP THROUGH 8 SECTORS +NXTS: PUSH BC +; + CALL DISPROG ; DISPLAY PROGRESS +; + LD IX,sector4k ; READ SECTOR + LD HL,MD_FREAD ; FROM ROM #1 + CALL MD_FNCALL +; + LD HL,MD_BANK ; SET CHIP #2 + SET 4,(HL) +; + LD A,(ERATYP) ; SKIP ERASE + OR A ; IF SECTOR ERASE + JR NZ,NOERA2 ; IS NOT SUPPORTED +; + LD HL,MD_FERAS ; ERASE SECTOR + CALL MD_FNCALL ; ON ROM #2 + OR A + JR NZ,VERF +; +NOERA2: LD IX,sector4k ; WRITE SECTOR + LD HL,MD_FWRIT ; ON ROM #2 + CALL MD_FNCALL +; + LD A,(WRTVER) ; VERIFY + OR A ; WRITE IF + JR Z,NOVER1 ; OPTION +; + LD IX,sector4k ; VERIFY + LD HL,MD_FVERI ; WRITE + CALL MD_FNCALL + OR A ; EXIT IF + JR NZ,VERF ; VERIFY FAILED +; +NOVER1: LD HL,MD_BANK ; RESET TO CHIP #1 + RES 4,(HL) +; + LD A,(MD_SECT) ; POINT TO + ADD A,$10 ; NEXT + LD (MD_SECT),A ; SECTOR +; + POP BC ; LOOP + DJNZ NXTS ; NEXT SECTOR +; + LD HL,MD_BANK ; POINT TO ; 00-15 = CHIP 1 + INC (HL) ; NEXT BANK ; 16-21 = CHIP 2 +; + POP BC ; LOOP + DJNZ NXTB ; NEXT BANK +; + JP Done1 ; SUCCESS. RETURN TO MENU +; +VERF: POP BC ; EXIT WITH FAIL + POP BC ; FAIL MESSAGE AND + JP FAILWF ; RETURN TO MENU +; +OPTIONV:LD A,(WRTVER) ; TOGGLE + CPL ; VERIFY + LD (WRTVER),A ; FLAG + JP MENULP ; BACK TO MENU +; +OPTIONC:LD HL,msgEnterUnit ; GET + CALL PRTSTR0 ; CONSOLE + CALL GETINP ; UNIT NUMBER + CP '0' + JR C,CONCLR + CP '9' + 1 + JR NC,CONCLR + SUB '0' + LD (CONDEV),A +CLRCON: CALL CONST ; EMPTY CONSOLE BUFFER + OR A ; SO WE DON'T HAVE ANY + JR Z,CONCLR ; FALSE ENTRIES + CALL CONIN + JR CLRCON + +CONCLR: JP MENULP ; BACK TO MENU +; +OPTIONS:LD HL,msgEnterUnit ; GET + CALL PRTSTR0 ; CONSOLE + CALL GETINP ; UNIT + CP '0' + JR C,CONCLR + CP '9' + 1 + JR NC,CONCLR + SUB '0' ; NUMBER + LD (SERDEV),A +; + JP MENULP ; BACK TO MENU +; +#IF (XFUDBG) +OPTIONT:LD HL,msgCRLF ; TEST DELAY 32S, 16S, 8S, 4S, 2S, 1S + CALL PRTSTR0 + LD B,32 ; START DELAY IS 32 SECONDS +TSTDLY: PUSH BC + LD C,'>' ; DISPLAY START + CALL CONOUT ; INDICATOR + LD A,B + CALL PRTHEXB + CALL GetCharTmo ; DELAY B SECONDS + LD C,'<' ; DISPLAY STOP + CALL CONOUT ; INDICATOR + POP BC + SRL B ; NEXT DELAY IS HALF PREVIOUS + JR NZ,TSTDLY ; RETURN TO MENU + JP MENULP ; WHEN DELAY GETS TO 1 SECOND +; +OPTIONH:LD A,8 ; TURN ON THE SBC-V2-004+ + OUT (RTCIO),A ; CLOCK DIVIDER + LD HL,TmoFct ; AND ADJUST + SRL (HL) ; DELAY FACTOR (/2) + JP MENULP ; BACK TO MENU +; +OPTIONF:LD HL,msgCRLF ; DISPLAY + CALL PRTSTR0 ; BANK + LD C,'b' ; SECTOR + CALL CONOUT ; TIMEOUT + LD A,(MD_BANK) ; CHIP + CALL PRTHEXB + LD C,'s' + CALL CONOUT + LD A,(MD_SECT) + CALL PRTHEXB + LD C,'t' + CALL CONOUT + LD A,(TmoFct) + CALL PRTHEXB + LD C,'c' + CALL CONOUT + LD A,(ERATYP) + CALL PRTHEXB +; + LD HL,msgCRLF ; DISPLAY + CALL PRTSTR0 ; ACK/NAK BYTE + LD HL,packet ; DISPLAY + LD B,3 ; LAST +DMPBUF2:LD A,(HL) ; NUMBERS + CALL PRTHEXB + LD C,' ' + CALL CONOUT + INC HL + DJNZ DMPBUF2 + LD HL,msgCRLF + CALL PRTSTR0 + LD B,128 ; DISPLAY + LD HL,packet+3 ; LAST +DMPBUF: LD A,(HL) ; PACKET + CALL PRTHEXB ; CONTENTS + LD C,' ' + CALL CONOUT + LD A,B + SUB 2 + AND %00001111 + CP %00001111 + JR NZ,DMPBUF1 + PUSH HL + LD HL,msgCRLF + CALL PRTSTR0 + POP HL +DMPBUF1:INC HL + DJNZ DMPBUF + JP MENULP +; +OPTIONR:LD HL,msgErase ; DISPLAY + CALL PRTSTR0 ; ERASE CHIP + LD HL,$1000 ; SET CHIP + LD (MD_FBAS),HL ; ADDRESS + LD HL,MD_FERAC ; ERASE + CALL MD_FNCALL ; AND WRITE + OR A + JP NZ,FAILWF + JP Done1 +; +OPTIONE:LD HL,msgErase ; DISPLAY + CALL PRTSTR0 ; ERASE CHIP + LD HL,MD_FERAC ; ERASE + CALL MD_FNCALL ; AND WRITE + OR A + JP NZ,FAILWF + JP Done1 +#ENDIF +; +SEROUT: PUSH HL ; SERIAL OUTPUT CHARACTER IN C + PUSH DE + PUSH BC + LD E,C + LD B,$01 + LD HL,SERDEV + LD C,(HL) + RST 08 + POP BC + POP DE + POP HL + RET +; +SERST: PUSH HL ; SERIAL STATUS. RETURN CHARACTERS AVAILABLE IN A + PUSH DE + PUSH BC + LD B,$02 + LD HL,SERDEV + LD C,(HL) + RST 08 + POP BC + POP DE + POP HL + RET +; +SERIN: PUSH HL ; SERIAL INPUT. WAIT FOR A CHARACTER ADD RETURN IT IN A + PUSH DE + PUSH BC + LD B,$00 + LD HL,SERDEV + LD C,(HL) + RST 08 + LD A,E + POP BC + POP DE + POP HL + RET +; +CONOUT: PUSH AF ; OUTPUT IS BLOCKED DURING THE + LD A,(BLKCOUT) ; FILE TRANSFER WHEN THE + OR A ; CONSOLE AND SERIAL LINE + JR Z,CONOUT1 ; ARE THE SAME + PUSH HL ; CONSOLE OUTPUT CHARACTER IN C + PUSH DE + PUSH BC + LD E,C + LD B,$01 + LD HL,CONDEV + LD C,(HL) + RST 08 + POP BC + POP DE + POP HL +CONOUT1:POP AF + RET +; +CONST: PUSH HL ; CONSOLE STATUS. RETURN CHARACTERS AVAILABLE IN A + PUSH DE + PUSH BC + LD B,$02 + LD HL,CONDEV + LD C,(HL) + RST 08 + POP BC + POP DE + POP HL + RET +; +CONIN: PUSH HL ; CONSOLE INPUT. WAIT FOR A CHARACTER ADD RETURN IT IN A + PUSH DE + PUSH BC + LD B,$00 + LD HL,CONDEV + LD C,(HL) + RST 08 + LD A,E + POP BC + POP DE + POP HL + RET +; +PRTHEXB:PUSH AF ; PRINT HEX BYTE IN A TO CONSOLE + PUSH DE + CALL HEXASC + LD C,D + CALL CONOUT + LD C,E + CALL CONOUT + POP DE + POP AF + RET + +HEXASC: LD D,A + CALL HEXCONV + LD E,A + LD A,D + RLCA + RLCA + RLCA + RLCA + CALL HEXCONV + LD D,A + RET +; +HEXCONV:AND 0FH ; CONVERT LOW NIBBLE OF A TO ASCII HEX + ADD A,90H + DAA + ADC A,40H + DAA + RET + +OPTION3:LD HL,$1000 ; CRC32 STARTING + LD (MD_FBAS),HL ; BANK $10 SECTOR $00 + LD B,16 ; 16 BANKS (512K) + JR CALCCRC + +OPTION1:LD HL,$0000 ; CRC32 STARTING + LD (MD_FBAS),HL ; BANK $00 SECTOR $00 + LD B,16 ; 16 BANKS (512K) + JR CALCCRC +; +OPTION2:LD HL,$0000 ; CRC32 STARTING + LD (MD_FBAS),HL ; BANK $00 SECTOR $00 + LD B,32 ; 32 BANKS (1024K) +; +CALCCRC:CALL COUTON ; TURN ON OUTPUT +; + LD HL,msgCalc + CALL PRTSTR0 +; + LD HL,$FFFF ; SET THE + LD (CRC),HL ; START CRC + LD (CRC+2),HL ; CONDITION + +; LD B,16 ; +CRCLP1: PUSH BC ; LOOP THROUGH ALL BANKS + LD B,8 ; LOOP THROUGH +CRCLP2: PUSH BC ; 8 SECTORS +; + PUSH BC + CALL DISPROG ; DISPLAY PROGRESS +; + LD IX,sector4k ; READ + LD HL,MD_FREAD ; A SECTOR + CALL MD_FNCALL + CALL CRC32 ; CALCULATE CRC + POP BC +; + LD A,(MD_SECT) ; POINT + ADD A,$10 ; TO NEXT + LD (MD_SECT),A ; SECTOR +; + POP BC ; NEXT + DJNZ CRCLP2 ; SECTOR +; + XOR A ; RESET SECTOR + LD (MD_SECT),A ; START +; + LD HL,MD_BANK ; POINT TO + INC (HL) ; NEXT BANK +; + POP BC ; NEXT + DJNZ CRCLP1 ; BANK +; + LD HL,msgCRC32 ; DISPLAY + CALL PRTSTR0 ; RESULT + LD HL,CRC+3 + LD B,4 +DISPCRC:LD A,$FF + XOR (HL) + CALL PRTHEXB + DEC HL + DJNZ DISPCRC +; + JP MENULP +; +CRC32: LD IX,sector4k ; CALCULATE + LD BC,4096 ; CRC32 OF + LD DE,(CRC) ; EACH SECTOR + LD HL,(CRC+2) +BYTELP: PUSH BC + LD A,(IX) + XOR E + LD B,8 +ROTLP: SRL H + RR L + RR D + RRA + JP NC,CLEAR + LD E,A + LD A,H + XOR $ED + LD H,A + LD A,L + XOR $B8 + LD L,A + LD A,D + XOR $83 + LD D,A + LD A,E + XOR $20 +CLEAR: DEC B + JP NZ,ROTLP + LD E,A + INC IX + POP BC + DEC BC + LD A,B + OR C + JP NZ,BYTELP + LD (CRC),DE + LD (CRC+2),HL + + RET +; +;====================================================================== +; CALCULATE BANK AND ADDRESS DATA FROM MEMORY ADDRESS +; +; ON ENTRY DE:HL CONTAINS 32 BIT MEMORY ADDRESS. +; ON EXIT B CONTAINS BANK SELECT BYTE +; C CONTAINS HIGH BYTE OF SECTOR ADDRESS +;====================================================================== +; +;MD_CALBAS: +; +; PUSH HL +; LD A,E ; BOTTOM PORTION OF SECTOR +; AND $0F ; ADDRESS THAT GETS WRITTEN +; RLC H ; WITH ERASE COMMAND BYTE +; RLA ; A15 GETS DROPPED OFF AND +; LD B,A ; ADDED TO BANK SELECT +; +; LD A,H ; TOP SECTION OF SECTOR +; RRA ; ADDRESS THAT GETS WRITTEN +; AND $70 ; TO BANK SELECT PORT +; LD C,A +; POP HL +; +; LD (MD_FBAS),BC ; SAVE BANK AND SECTOR FOR USE IN FLASH ROUTINES +; RET +; +MD_FSTART: .EQU $ ; FLASH ROUTINES WHICH GET RELOCATED TO HIGH MEMORY +; +;====================================================================== +; COMMON FUNCTION CALL FOR: +; +; MD_FIDEN_R - IDENTIFY FLASH CHIP +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; ON EXIT BC CONTAINS THE CHIP ID BYTES. +; A NO STATUS IS RETURNED +; +; MD_FERAS_R - ERASE FLASH SECTOR +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; ON EXIT A RETURNS STATUS 0=SUCCESS NZ=FAIL +; +; MD_FREAD_R - READ FLASH SECTOR +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; IX POINTS TO WHERE TO SAVE DATA +; ON EXIT A NO STATUS IS RETURNED +; +; MD_VERI_R - VERIFY FLASH SECTOR +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; IX POINTS TO DATA TO COMPARE. +; ON EXIT A RETURNS STATUS 0=SUCCESS NZ=FAIL +; +; MD_FWRIT_R - WRITE FLASH SECTOR +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; IX POINTS TO DATA TO BE WRITTEN +; ON EXIT A NO STATUS IS RETURNED +; +; MD_FERAC_R - ERASE FLASH CHIP +; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED +; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED +; ON EXIT A RETURNS STATUS 0=SUCCESS FF=FAIL +; +; GENERAL OPERATION: +; FLASH LIBRARY CODE NEEDS TO BE RELOCATED TO UPPER MEMORY +; STACK NEEDS TO BE SETUP IN UPPER MEMORY +; DEPENDING ON ROUTINE, RETURNS WITH STATUS CODE IN A. +;====================================================================== +; +MD_FNCALL: + LD DE,$0000 ; PRESET DE TO SAVE SPACE + LD BC,(MD_FBAS) ; PUT BANK AND SECTOR DATA IN BC +; + LD A,(HB_CURBNK) ; WE ARE STARTING IN HB_CURBNK +; + HB_DI + CALL MD_FJPHL + HB_EI +; + LD A,C ; RETURN WITH STATUS IN A + RET +; +MD_FJPHL: + JP (HL) +; +#INCLUDE "flashlib.inc" +; +MD_FEND .EQU $ +MD_CSIZ .EQU MD_FEND-MD_FSTART ; HOW MUCH SPACE WE NEED FOR RELOCATABLE CODE +; +MD_FIDEN .EQU HBX_LOC-MD_CSIZ+MD_FIDEN_R-MD_FSTART ; CALL ADDRESS FOR IDENTIFY FLASH CHIP +MD_FERAS .EQU HBX_LOC-MD_CSIZ+MD_FERAS_R-MD_FSTART ; CALL ADDRESS FOR ERASE FLASH SECTOR +MD_FREAD .EQU HBX_LOC-MD_CSIZ+MD_FREAD_R-MD_FSTART ; CALL ADDRESS FOR READ FLASH SECTOR +MD_FVERI .EQU HBX_LOC-MD_CSIZ+MD_FVERI_R-MD_FSTART ; CALL ADDRESS FOR VERIFY FLASH SECTOR +MD_FWRIT .EQU HBX_LOC-MD_CSIZ+MD_FWRIT_R-MD_FSTART ; CALL ADDRESS FOR WRITE FLASH SECTOR +MD_FERAC .EQU HBX_LOC-MD_CSIZ+MD_FERAC_R-MD_FSTART ; CALL ADDRESS FOR ERASE FLASH CHIP +; +; Message strings +; +msgHeader: .DB CR,LF,CR,LF,"ROMWBW XMODEM FLASH UPDATER",CR,LF,0 +msgConfirm: .DB CR,LF,CR,LF,"ENTER Y TO CONFIRM OVERWRITE : ",0 +msgInstr: .DB CR,LF,CR,LF,"START TRANSFER OF YOUR UPDATE IMAGE OR ROM",CR,LF,0 +msgUserEx: .DB CR,LF,"UPDATER EXITED BY USER",CR,LF,0 +msgBank: .DB CR,LF,"BANK ",0 +msgUnsupC: .DB CR,LF,"FLASH CHIP NOT SUPPORTED",CR,LF,0 +msgReboot: .DB CR,LF,"REBOOTING ...",CR,LF,0 +msgCopying: .DB CR,LF,"COPYING ...",CR,LF,0 +msgCalc: .DB CR,LF,"CALCULATING ...",CR,LF,0 +msgErase: .DB CR,LF,"ERASING ...",CR,LF,0 +msgCRC32: .DB CR,LF,CR,LF,"CRC32 : ",0 +msgFailWrt: .DB CR,LF,"FLASH WRITE FAILED",CR,LF,0 +msgFailure: .DB CR,LF,"TRANSMISSION FAILED",CR,LF,0 +msgCancel: .DB CR,LF,"TRANSMISSION CANCELLED",CR,LF,0 +msgConsole: .DB CR,LF,CR,LF,"(C) Set Console Device : ",0 +msgIODevice: .DB CR,LF,"(S) Set Serial Device : ",0 +msgWriteV: .DB CR,LF,"(V) Toggle Write Verify : ",0 +msgBegin: .DB CR,LF,"(R) Reboot" + .DB CR,LF,"(U) Begin Update" + .DB CR,LF,"(X) Exit to Rom Loader" + .DB CR,LF,"(D) Duplicate Flash #1 to #2" + .DB CR,LF,"(1) CRC 512K Flash" + .DB CR,LF,"(2) CRC 1024K Flash" +#IF (XFUDBG) + .DB CR,LF,"(H) Select half speed" + .DB CR,LF,"(T) Test timeout" + .DB CR,LF,"(F) Dump Debug Data" + .DB CR,LF,"(E) Erase Flash chip #1" + .DB CR,LF,"(Z) Erase Flash chip #2" + .DB CR,LF,"(3) CRC Flash chip #2" +#ENDIF + .DB CR,LF,CR,LF,"Select : ",0 +msgSuccess: .DB CR,LF,CR,LF,"COMPLETED WITHOUT ERRORS ",CR,LF,0 +msgEnterUnit: .DB CR,LF,"ENTER UNIT NUMBER : ",0 +msgCRLF: .DB CR,LF,0 +msgYES: .DB "YES",0 +msgNO: .DB "NO",0 +msgPacErr: .DB CR,LF,"PACKET COUNT MISMATCH ERROR",CR,LF,0 +msgChkSum .DB CR,LF,"CHECKSUM ERROR",CR,LF,0 +msgRetry .DB CR,LF,"ERROR, RETRY COUNT EXCEEDED",CR,LF,0 +msgTimout .DB CR,LF,"ERROR, RECEIVE TIMEOUT",CR,LF,0 +; +; Variables +; +CONDEV: .DB $00 ; HBIOS CONSOLE DEVICE NUMBER +SERDEV: .DB $00 ; HBIOS SERIAL DEVICE NUMBER USED FOR XMODEM TRANSFER +WRTVER: .DB $FF ; WRITE VERIFY OPTION FLAG +VERRES: .DB $00 ; WRITE VERIFY RESULT +BLKCOUT: .DB $FF ; BLOCK TEXT OUTPUT DURING TRANSFER IF ZERO +ERATYP .DB $00 ; HOLDS THE ERASE TYPE FLAG FOR VARIOUS CHIPS +oldSP: .DW 0 ; The orginal SP to be restored before exiting +retrycnt: .DB 0 ; Counter for retries before giving up +chksum: .DB 0 ; For calculating the checksum of the packet +pktNo: .DB 0 ; Current packet Number +pktNo1c: .DB 0 ; Current packet Number 1-complemented +MD_FBAS .DW $FFFF ; CURRENT BANK AND SECTOR +MD_SECT .EQU MD_FBAS ; BANK BYTE +MD_BANK .EQU MD_FBAS+1 ; SECTOR BYTE +CRC .DW $FFFF ; CRC32 + .DW $FFFF +; +packet: .DB 0 ; SOH + .DB 0 ; PacketN + .DB 0 ; -PacketNo, + .FILL 128,0 ; data*128, + .DB 0 ; chksum +; +sector4k: .EQU $ ; 32 PACKETS GET ACCUMULATED HERE BEFORE FLASHING +; +SLACK .EQU (USR_END - $) + .FILL SLACK,$FF + .ECHO "User ROM space remaining: " + .ECHO SLACK + .ECHO " bytes.\n" + .END diff --git a/Source/HBIOS/usrrom.asm b/Source/HBIOS/usrrom.asm index 9a03a38d..ead329be 100644 --- a/Source/HBIOS/usrrom.asm +++ b/Source/HBIOS/usrrom.asm @@ -8,14 +8,14 @@ LF .EQU 0AH ; .ORG USR_LOC ; - LD HL,BOOTMSG ; INTRODUCTION + LD HL,BOOTMSG ; INTRODUCTION CALL PRTSTR - CALL CIN ; DO STUFF + CALL CIN ; DO STUFF ; - LD A,00H ; RETURN TO ROM LOADER - LD HL,0000H - JP 0FFF9H + LD B,BF_SYSRESET ; SYSTEM RESTART + LD C,BF_SYSRES_WARM ; WARM START + CALL $FFF0 ; CALL HBIOS ; RET ; ; diff --git a/Source/HBIOS/util.asm b/Source/HBIOS/util.asm index 3d9ee4d5..707c7ddf 100644 --- a/Source/HBIOS/util.asm +++ b/Source/HBIOS/util.asm @@ -125,7 +125,7 @@ PRTSTR: ; PRINT A STRING DIRECT: REFERENCED BY POINTER AT TOP OF STACK ; STRING MUST BE TERMINATED BY '$' ; USAGE: -; CALL PRTSTR +; CALL PRTSTRD ; .DB "HELLO$" ; ... ; @@ -183,6 +183,17 @@ PRTHEXWORD: 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: @@ -295,7 +306,7 @@ DB_CONTD: JP DB_BLKRD ; DB_END: - RET + 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. @@ -322,7 +333,7 @@ PRTIDXMSK1: 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 +; 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 @@ -332,6 +343,8 @@ PRTIDXDEA: PUSH BC LD C,A ; INDEX COUNT OR A + LD A,0 + LD (PRTIDXCNT),A ; RESET CHARACTER COUNT PRTIDXDEA1: JR Z,PRTIDXDEA3 PRTIDXDEA2: @@ -346,6 +359,9 @@ PRTIDXDEA3: ; CALL WRITESTR ; FALL THROUGH TO WRITESTR ; RET ; +PRTIDXCNT: + .DB 0 ; CHARACTER COUNT +; ; OUTPUT A '$' TERMINATED STRING AT DE ; WRITESTR: @@ -355,6 +371,9 @@ WRITESTR1: CP '$' ; TEST FOR STRING TERMINATOR JP Z,WRITESTR2 CALL COUT + LD A,(PRTIDXCNT) + INC A + LD (PRTIDXCNT),A INC DE JP WRITESTR1 WRITESTR2: @@ -370,17 +389,6 @@ TSTPT: POP DE JR REGDMP ; DUMP REGISTERS AND RETURN ; -; PANIC: TRY TO DUMP MACHINE STATE -; -PANIC: - PUSH DE - LD DE,STR_PANIC - CALL WRITESTR - POP DE - CALL XREGDMP ; DUMP REGISTERS - CALL CONTINUE ; CHECK W/ USER - RET -; ; ; REGDMP: @@ -410,7 +418,7 @@ XREGDMP: LD A,'@' CALL COUT POP AF - + PUSH BC LD BC,(REGDMP_PC) CALL PRTHEXWORD ; PC @@ -434,7 +442,7 @@ XREGDMP: CALL PC_COLON LD BC,(REGDMP_SP) CALL PRTHEXWORD ; SP - + CALL PC_COLON PUSH IX POP BC @@ -454,7 +462,7 @@ XREGDMP: 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 ; @@ -467,34 +475,10 @@ REGDMP_SP .DW 0 ; ; ; -CONTINUE: - PUSH AF - PUSH DE - LD DE,STR_CONTINUE - CALL WRITESTR - POP DE -CONTINUE1: - CALL CIN - CP 'Y' - JR Z,CONTINUE3 - CP 'y' - JR Z,CONTINUE3 - CP 'N' - JR Z,CONTINUE2 - CP 'n' - JR Z,CONTINUE2 - JR CONTINUE1 -CONTINUE2: - HALT -CONTINUE3: - POP AF - RET ; ; -; -STR_PANIC .DB "\r\n\r\n>>> PANIC: $" +STR_HALT .TEXT "\r\n\r\n*** System Halted ***$" STR_TSTPT .TEXT "\r\n+++ TSTPT: $" -STR_CONTINUE .TEXT " Continue? (Y/N): $" ;STR_AF .DB " AF=$" ;STR_BC .DB " BC=$" ;STR_DE .DB " DE=$" @@ -666,8 +650,8 @@ DELAY_INIT: #IF (BIOS == BIOS_UNA) LD C,$F8 ; UNA BIOS GET PHI FUNCTION RST 08 ; RETURNS SPEED IN HZ IN DE:HL - LD B,4 ; DIVIDE MHZ IN DE:HL BY 100000H -DELAY_INIT0: + LD B,4 ; DIVIDE MHZ IN DE:HL BY 100000H +DELAY_INIT0: SRL D ; ... TO GET APPROX CPU SPEED IN RR E ; ...MHZ. THROW AWAY HL, AND DJNZ DELAY_INIT0 ; ...RIGHT SHIFT DE BY 4. @@ -772,13 +756,13 @@ DIV16: DIV16A: SCF RL C - RLA - ADC HL,HL - SBC HL,DE - JR NC,DIV16B - ADD HL,DE - DEC C -DIV16B: + 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 @@ -985,7 +969,7 @@ SUB32: RET ; ; INC32 (HL) -; INCREMENT 32 BIT BINARY AT ADDRESS +; INCREMENT 32 BIT BINARY AT ADDRESS ; INC32HL: INC (HL) diff --git a/Source/HBIOS/vdu.asm b/Source/HBIOS/vdu.asm index bc888aa5..bb37c14a 100644 --- a/Source/HBIOS/vdu.asm +++ b/Source/HBIOS/vdu.asm @@ -47,40 +47,40 @@ VDU_BLNK .EQU VDU_NOBL ; DEFAULT BLINK RATE TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER ; #IF (VDUSIZ=V80X24) -DLINES .EQU 24 +DLINES .EQU 24 DROWS .EQU 80 DSCANL .EQU 10 #ENDIF #IF (VDUSIZ=V80X25) -DLINES .EQU 25 +DLINES .EQU 25 DROWS .EQU 80 DSCANL .EQU 10 #ENDIF #IF (VDUSIZ=V80X30) -DLINES .EQU 30 +DLINES .EQU 30 DROWS .EQU 80 DSCANL .EQU 8 #ENDIF #IF (VDUSIZ=V80X25B) -DLINES .EQU 25 +DLINES .EQU 25 DROWS .EQU 80 DSCANL .EQU 12 #ENDIF #IF (VDUSIZ=V80X24B) -DLINES .EQU 24 +DLINES .EQU 24 DROWS .EQU 80 DSCANL .EQU 12 #ENDIF ; #IF VDU_CSTY=VDU_BLOK -VDU_R10 .EQU (VDU_BLNK + $00) +VDU_R10 .EQU (VDU_BLNK + $00) VDU_R11 .EQU DSCANL-1 #ENDIF ; #IF VDU_CSTY=VDU_ULIN -VDU_R10 .EQU (VDU_BLNK + DSCANL-1) +VDU_R10 .EQU (VDU_BLNK + DSCANL-1) VDU_R11 .EQU DSCANL-1 -#ENDIF +#ENDIF ; ;====================================================================== ; VDU DRIVER - INITIALIZATION @@ -127,7 +127,7 @@ VDU_INIT1: XOR A ; SIGNAL SUCCESS RET -; +; ;====================================================================== ; VDU DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS ;====================================================================== @@ -150,6 +150,7 @@ VDU_FNTBL: .DW PPK_READ #IF (($ - VDU_FNTBL) != (VDA_FNCNT * 2)) .ECHO "*** INVALID VDU FUNCTION TABLE ***\n" + !!!!! #ENDIF VDU_VDAINI: @@ -165,7 +166,7 @@ VDU_VDAQRY: LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED XOR A ; SIGNAL SUCCESS RET - + VDU_VDARES: LD DE,0 LD (VDU_OFFSET),DE @@ -180,6 +181,8 @@ VDU_VDARES: VDU_VDADEV: LD D,VDADEV_VDU ; D := DEVICE TYPE LD E,0 ; E := PHYSICAL UNIT IS ALWAYS ZERO + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,VDU_BASE ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET @@ -202,26 +205,26 @@ VDU_VDASCS: XOR A RET - + VDU_VDASCP: CALL VDU_XY XOR A RET - + VDU_VDASAT: XOR A RET - + VDU_VDASCO: XOR A RET - + VDU_VDAWRC: LD A,E CALL VDU_PUTCHAR XOR A RET - + VDU_VDAFIL: LD A,E ; FILL CHARACTER GOES IN A EX DE,HL ; FILL LENGTH GOES IN DE @@ -236,9 +239,9 @@ VDU_VDACPY: POP BC ; RECOVER LENGTH IN BC LD DE,(VDU_POS) ; PUT DEST IN DE JP VDU_BLKCPY ; DO A BLOCK COPY - + RET - + VDU_VDASCR: LD A,E ; LOAD E INTO A OR A ; SET FLAGS @@ -293,7 +296,7 @@ VDU_WRREGX: ;---------------------------------------------------------------------- ; READ SY6845 REGISTERS ; VDU_RDREG READS VDU REGISTER SPECIFIED IN C AND RETURNS VALUE IN A -; VDU_RDREGX READS VDU REGISTER PAIR SPECIFIED BY C, C+1 +; VDU_RDREGX READS VDU REGISTER PAIR SPECIFIED BY C, C+1 ; AND RETURNS VALUE IN HL ;---------------------------------------------------------------------- ; @@ -398,13 +401,13 @@ VDU_PUTCHAR: INC HL ; NEW CURSOR POSITION LD C,14 ; CURSOR POSITION REGISTER PAIR CALL VDU_WRREGX ; DO IT - + LD A,31 ; PREP VDU FOR DATA R/W OUT (VDU_REG),A CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY LD A,B OUT (VDU_RAMWR),A ; OUTPUT CHAR TO VDU - + RET ; ;---------------------------------------------------------------------- @@ -431,7 +434,7 @@ VDU_FILL: OUT (VDU_REG),A VDU_FILL1: LD A,D ; CHECK NUMBER OF FILL CHARS LEFT - OR E + OR E RET Z ; ALL DONE, RETURN CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY LD A,B @@ -481,7 +484,7 @@ VDU_BLKCPY1: ; VIDEO RAM -> BUFFER COPY LOOP OUT (VDU_REG),A ; DO IT LD HL,VDU_BUF ; HL POINTS TO WORK BUFFER LD C,VDU_RAMWR ; LOAD C WITH VDU WRITE REGISTER - + VDU_BLKCPY2: ; BUFFER -> VIDEO RAM COPY LOOP CALL VDU_WAITRDY ; WAIT FOR VDU OUTI ; WRITE BYTE, DEC B, INC HL @@ -501,7 +504,7 @@ VDU_SCROLL: LD (VDU_OFFSET),HL LD C,12 CALL VDU_WRREGX - + ; FILL EXPOSED LINE LD HL,(VDU_POS) PUSH HL @@ -512,7 +515,7 @@ VDU_SCROLL: CALL VDU_FILL POP HL LD (VDU_POS),HL - + ; ADJUST CURSOR POSITION AND RETURN LD HL,(VDU_OFFSET) LD DE,(VDU_POS) @@ -543,7 +546,7 @@ VDU_RSCROLL: CALL VDU_FILL POP HL LD (VDU_POS),HL - + ; ADJUST CURSOR POSITION AND RETURN LD HL,(VDU_OFFSET) LD DE,(VDU_POS) @@ -566,7 +569,7 @@ VDU_BUF .FILL 256,0 ; COPY BUFFER ; CCIR 625/50 VERSION (USED IN MOST OF THE WORLD) ; JUMPER K1 2-3, K2 1-2 FOR 2MHz CHAR CLOCK ; -; THE CCIR 625/50 TELEVISION STANDARD HAS 625 LINES INTERLACED AT 50 FIELDS PER SECOND. THIS WORKS +; THE CCIR 625/50 TELEVISION STANDARD HAS 625 LINES INTERLACED AT 50 FIELDS PER SECOND. THIS WORKS ; OUT AS 50 FIELDS OF 312.5 LINES PER SECOND NON-INTERLACED AS USED HERE. ; HORIZONTAL LINE WIDTH IS 64uS. FOR A 2 MHz CHARACTER CLOCK (R0+1)/2000000 = 64uS ; NEAREST NUMBER OF LINES IS 312 = (R4+1) * (R9+1) + R5. @@ -658,7 +661,7 @@ VDU_INIT6845: .DB 00CH ; R3 SYNC WIDTHS .DB 19H ; R4 VERTICAL TOTAL (TOTAL CHARS IN A FRAME -1) (312/DLINES)-1 .DB 00H ; R5 VERTICAL TOTAL ADJUST (312-(R4+1)*DSCANL) - .DB DLINES ; R6 VERTICAL DISPLAY + .DB DLINES ; R6 VERTICAL DISPLAY .DB 019H ; R7 VERTICAL SYNC (DLINES .. R4) .DB 078H ; R8 MODE .DB DSCANL-1 ; R9 SCAN LINE (LINES PER CHAR AND SPACING -1) @@ -680,7 +683,7 @@ VDU_INIT6845: .DB 00CH ; R3 SYNC WIDTHS .DB 19H ; R4 VERTICAL TOTAL (TOTAL CHARS IN A FRAME -1) (312/DLINES)-1 .DB 00H ; R5 VERTICAL TOTAL ADJUST (312-(R4+1)*DSCANL) - .DB DLINES ; R6 VERTICAL DISPLAY + .DB DLINES ; R6 VERTICAL DISPLAY .DB 018H ; R7 VERTICAL SYNC (DLINES .. R4) .DB 078H ; R8 MODE .DB DSCANL-1 ; R9 SCAN LINE (LINES PER CHAR AND SPACING -1) diff --git a/Source/HBIOS/vga.asm b/Source/HBIOS/vga.asm index 5a285376..dea1aea8 100644 --- a/Source/HBIOS/vga.asm +++ b/Source/HBIOS/vga.asm @@ -70,12 +70,12 @@ VGA_89BIT .EQU VGA_8BIT #ENDIF ; #IF VGA_CSTY=VGA_BLOK -VGA_R10 .EQU (VGA_BLNK + $00) +VGA_R10 .EQU (VGA_BLNK + $00) VGA_R11 .EQU VGA_SCANL-1 #ENDIF ; #IF VGA_CSTY=VGA_ULIN -VGA_R10 .EQU (VGA_BLNK + VGA_SCANL-1) +VGA_R10 .EQU (VGA_BLNK + VGA_SCANL-1) VGA_R11 .EQU VGA_SCANL-1 #ENDIF ; @@ -85,7 +85,7 @@ TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER ; ; DRIVER UTILIZES THE MULTIPLE DISPLAY WINDOW FEATURE OF THE CRTC TO ACCOMPLISH ; FULL SCREEN SCROLLING WITHOUT THE NEED TO MOVE DISPLAY RAM BYTES. -; +; ; SCREEN 1 IMPLICITLY STARTS AT PHYSICAL ROW 0 ; SCREEN 1 RAM ADDRESS POINTER POINTS TO SCREEN OFFSET (R12/R13) ; SCREEN 2 ROW DEFINES WHERE BUFFER BYTE 0 WILL BE DISPLAYED (R18) @@ -163,6 +163,7 @@ VGA_FNTBL: .DW KBD_READ #IF (($ - VGA_FNTBL) != (VDA_FNCNT * 2)) .ECHO "*** INVALID VGA FUNCTION TABLE ***\n" + !!!!! #ENDIF VGA_VDAINI: @@ -179,13 +180,13 @@ VGA_VDAQRY: LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET XOR A ; SIGNAL SUCCESS RET - + VGA_VDARES: LD A,$07 ; ATTRIBUTE IS STANDARD WHITE ON BLACK LD (VGA_ATTR),A ; SAVE IT XOR A ; ZERO (REVERSE, UNDERLINE, BLINK) LD (VGA_RUB),A ; SAVE IT - + LD DE,0 ; ROW = 0, COL = 0 CALL VGA_XY ; SEND CURSOR TO TOP LEFT LD A,' ' ; BLANK THE SCREEN @@ -193,27 +194,32 @@ VGA_VDARES: CALL VGA_FILL ; DO IT LD DE,0 ; ROW = 0, COL = 0 CALL VGA_XY ; SEND CURSOR TO TOP LEFT - + LD HL,$0404 | VGA_89BIT; SET VIDEO ENABLE BIT CALL VGA_SETCFG ; DO IT - + XOR A RET VGA_VDADEV: LD D,VDADEV_VGA ; D := DEVICE TYPE LD E,0 ; E := PHYSICAL UNIT IS ALWAYS ZERO + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,VGA_BASE ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET - + VGA_VDASCS: - CALL PANIC ; NOT IMPLEMENTED (YET) - + CALL SYSCHK ; NOT IMPLEMENTED (YET) + LD A,ERR_NOTIMPL + OR A + RET + VGA_VDASCP: CALL VGA_XY ; SET CURSOR POSITION XOR A ; SIGNAL SUCCESS RET - + VGA_VDASAT: ; INCOMING IS: -----RUB (R=REVERSE, U=UNDERLINE, B=BLINK) ; @@ -222,7 +228,7 @@ VGA_VDASAT: LD A,E LD (VGA_RUB),A ; SAVE IT JR VGA_VDASCO2 ; IMPLEMENT SETTING - + VGA_VDASCO: ; INCOMING IS: IBGRIBGR (I=INTENSITY, B=BLUE, G=GREEN, R=RED) ; TRANSFORM TO: -RGBIRGB (DISCARD INTENSITY BIT IN HIGH NIBBLE) @@ -269,13 +275,13 @@ VGA_VDASCO2: VGA_VDASCO3: XOR A ; SIGNAL SUCCESS RET - + VGA_VDAWRC: LD A,E ; CHARACTER TO WRITE GOES IN A CALL VGA_PUTCHAR ; PUT IT ON THE SCREEN XOR A ; SIGNAL SUCCESS RET - + VGA_VDAFIL: LD A,E ; FILL CHARACTER GOES IN A EX DE,HL ; FILL LENGTH GOES IN DE @@ -291,7 +297,7 @@ VGA_VDACPY: POP BC ; RECOVER LENGTH IN BC LD DE,(VGA_POS) ; PUT DEST IN DE JP VGA_BLKCPY ; DO A BLOCK COPY - + VGA_VDASCR: LD A,E ; LOAD E INTO A OR A ; SET FLAGS @@ -522,7 +528,7 @@ VGA_LOADFONT: LD (VGA_STACK),SP ; SAVE STACK LD HL,(VGA_STACK) ; AND SHIFT IT LD DE,$2000 ; DOWN 4KB TO - CCF ; CREATE A + OR A ; CREATE A SBC HL,DE ; DECOMPRESSION BUFFER LD SP,HL ; HL POINTS TO BUFFER EX DE,HL ; START OF STACK BUFFER @@ -543,7 +549,7 @@ VGA_LOADFONT2: INC HL ; NEXT FONT BYTE INC DE ; NEXT MEM BYTE DJNZ VGA_LOADFONT2 - + LD BC,16-VGA_SCANL ; MOVE TO NEXT EX DE,HL ; 16 BYTE ADD HL,BC ; CHARACTER @@ -586,7 +592,7 @@ VGA_XY2IDX: CALL MULT8 ; MULTIPLY TO GET ROW OFFSET LD E,A ; GET COLUMN BACK ADD HL,DE ; ADD IT IN - + LD DE,(VGA_OFF) ; SCREEN OFFSET ADD HL,DE ; ADJUST ; @@ -651,7 +657,7 @@ VGA_FILL: LD HL,(VGA_POS) ; GET CURRENT POSITION SLA L ; MULTIPLY BY 2 RL H ; ... 2 BYTES PER CHAR - + VGA_FILL1: ; FILL ONE POSITION (CHAR & ATTR) LD C,VGA_HI ; C := VGA ADR HI @@ -669,7 +675,7 @@ VGA_FILL1: #ENDIF LD A,(VGA_ATTR) ; GET CUR ATTR OUT (C),A ; OUTPUT ATTR - + ; CHECK COUNT DEC DE ; DECREMENT COUNT LD A,D ; TEST FOR @@ -755,7 +761,7 @@ VGA_SCROLL6: LD (VGA_POS),HL ; SAVE IT LD C,14 ; CURSOR 1 POS REG CALL VGA_REGWRX ; COMMIT - + RET ; ;---------------------------------------------------------------------- @@ -822,13 +828,13 @@ VGA_BLKCPY: SLA C RL B PUSH BC ; COUNT ==> TOS - + ; ADJUST HL & DE FOR SCREEN OFFSET/WRAP CALL VGA_BLKCPY4 ; DO HL EX DE,HL ; SWAP CALL VGA_BLKCPY4 ; DO OTHER EX DE,HL ; SWAP BACK - + VGA_BLKCPY1: #IF (VGA_NICE) CALL VGA_WAITSB ; WAIT FOR RETRACE @@ -842,7 +848,7 @@ VGA_BLKCPY1: INC C ; C := VGA_DATA IN A,(C) ; A := (HL) - ; COPY TO DESTINATION + ; COPY TO DESTINATION LD C,VGA_HI ; C := VGA_HI OUT (C),D ; VGA_HI := SOURCE HI (H) INC C ; C := VGA_LO @@ -945,7 +951,7 @@ REGS_VGA: .DB 18,-1 ; S2 ROW - 1 .DB 27,12 ; VERT SYNC POS ADJ .DB 30,$01 | $08 ; CTL 1, 2 WINDOWS & ENABLE R27 VSYNC FINE ADJ - + .DB $FF ; END MARKER #ENDIF #IF (VGASIZ=V80X30) @@ -966,7 +972,7 @@ REGS_VGA: .DB 10,VGA_R10 ; CURSOR START & CURSOR BLINK .DB 11,VGA_R11 ; CURSOR END .DB 12,0 ; SCRN 1 START (HI) - .DB 13,0 ; SCRN 1 START (LO) + .DB 13,0 ; SCRN 1 START (LO) .DB 18,-1 ; S2 ROW - 1 .DB 27,0 ; VERT SYNC POS ADJ .DB 30,$01 | $08 ; CTL 1, 2 WINDOWS & ENABLE R27 VSYNC FINE ADJ @@ -990,7 +996,7 @@ REGS_VGA: .DB 10,VGA_R10 ; CURSOR START & CURSOR BLINK .DB 11,VGA_R11 ; CURSOR END .DB 12,0 ; SCRN 1 START (HI) - .DB 13,0 ; SCRN 1 START (LO) + .DB 13,0 ; SCRN 1 START (LO) .DB 18,-1 ; S2 ROW - 1 .DB 27,0 ; VERT SYNC POS ADJ .DB 30,$01 | $08 ; CTL 1, 2 WINDOWS & ENABLE R27 VSYNC FINE ADJ @@ -998,7 +1004,7 @@ REGS_VGA: #ENDIF #IF (VGASIZ=V80X60) ;=============================================================================== -; 80x60X8 60hz REGISTER VALUES +; 80x60X8 60hz REGISTER VALUES ;=============================================================================== ; REGS_VGA: @@ -1014,7 +1020,7 @@ REGS_VGA: .DB 10,VGA_R10 ; CURSOR START & CURSOR BLINK .DB 11,VGA_R11 ; CURSOR END .DB 12,0 ; SCRN 1 START (HI) - .DB 13,0 ; SCRN 1 START (LO) + .DB 13,0 ; SCRN 1 START (LO) .DB 18,-1 ; S2 ROW - 1 .DB 27,0 ; VERT SYNC POS ADJ .DB 30,$01 | $08 ; CTL 1, 2 WINDOWS & ENABLE R27 VSYNC FINE ADJ diff --git a/Source/HBIOS/z180.inc b/Source/HBIOS/z180.inc index 5ceb0bae..196019ff 100644 --- a/Source/HBIOS/z180.inc +++ b/Source/HBIOS/z180.inc @@ -64,4 +64,4 @@ Z180_BBR .EQU Z180_BASE + $39 ; MMU BANK BASE REGISTER Z180_CBAR .EQU Z180_BASE + $3A ; MMU COMMON/BANK AREA REGISTER ; Z180_OMCR .EQU Z180_BASE + $3E ; OPERATION MODE CONTROL -Z180_ICR .EQU $3F ; I/O CONTROL REGISTER (NOT RELOCATED!!!) +Z180_ICR .EQU Z180_BASE + $3F ; I/O CONTROL REGISTER diff --git a/Source/HBIOS/z280.inc b/Source/HBIOS/z280.inc new file mode 100644 index 00000000..5da6234c --- /dev/null +++ b/Source/HBIOS/z280.inc @@ -0,0 +1,76 @@ +; +; Z280 CPU CONTROL REGISTERS (VIA LDCTL) +; +Z280_MSR .EQU $00 ; MASTER STATUS REG +Z280_ISR .EQU $16 ; INTERRUPT STATUS REG +Z280_VPR .EQU $06 ; INT/TRAP VECT PTR REG +Z280_IOPR .EQU $08 ; I/O PAGE REG +Z280_BTIR .EQU $FF ; BUS TIMING & INIT REG +Z280_BTCR .EQU $02 ; BUS TIMING & CONTROL REG +Z280_SLR .EQU $04 ; STACK LIMIT REG +Z280_TCR .EQU $10 ; TRAP CONTROL REG +Z280_CCR .EQU $12 ; CACHE CONTROL REG +Z280_LAR .EQU $14 ; LOCAL ADDRESS REG +; +; Z280 PAGE $FF REGSISTER ADDRESSES +; +Z280_RRR .EQU $E8 ; Z280 REFRESH RATE REG +; +Z280_MMUMCR .EQU $F0 ; Z280 MMU MASTER CONTROL REG +Z280_MMUPDRPTR .EQU $F1 ; Z280 MMU PDR POINTER REG +Z280_MMUINV .EQU $F2 ; Z280 MMU INVALIDATION PORT +Z280_MMUBLKMOV .EQU $F4 ; Z280 MMU BLOCK MOVE PORT +Z280_MMUPDR .EQU $F5 ; Z280 MMU PDR PORT +; +Z280_DMA0_DSTL .EQU $00 ; DMA0 DESTINATION ADDRESS LOW +Z280_DMA0_DSTH .EQU $01 ; DMA0 DESTINATION ADDRESS HIGH +Z280_DMA0_SRCL .EQU $02 ; DMA0 SOURCE ADDRESS LOW +Z280_DMA0_SRCH .EQU $03 ; DMA0 SOURCE ADDRESS HIGH +Z280_DMA0_CNT .EQU $04 ; DMA0 COUNT +Z280_DMA0_TDR .EQU $05 ; DMA0 TRANSACTION DESCRIPTION REG +; +Z280_DMA1_DSTL .EQU $08 ; DMA1 DESTINATION ADDRESS LOW +Z280_DMA1_DSTH .EQU $09 ; DMA1 DESTINATION ADDRESS HIGH +Z280_DMA1_SRCL .EQU $0A ; DMA1 SOURCE ADDRESS LOW +Z280_DMA1_SRCH .EQU $0B ; DMA1 SOURCE ADDRESS HIGH +Z280_DMA1_CNT .EQU $0C ; DMA1 COUNT +Z280_DMA1_TDR .EQU $0D ; DMA1 TRANSACTION DESCRIPTION REG +; +Z280_DMA2_DSTL .EQU $10 ; DMA2 DESTINATION ADDRESS LOW +Z280_DMA2_DSTH .EQU $11 ; DMA2 DESTINATION ADDRESS HIGH +Z280_DMA2_SRCL .EQU $12 ; DMA2 SOURCE ADDRESS LOW +Z280_DMA2_SRCH .EQU $13 ; DMA2 SOURCE ADDRESS HIGH +Z280_DMA2_CNT .EQU $14 ; DMA2 COUNT +Z280_DMA2_TDR .EQU $15 ; DMA2 TRANSACTION DESCRIPTION REG +; +Z280_DMA3_DSTL .EQU $18 ; DMA3 DESTINATION ADDRESS LOW +Z280_DMA3_DSTH .EQU $19 ; DMA3 DESTINATION ADDRESS HIGH +Z280_DMA3_SRCL .EQU $1A ; DMA3 SOURCE ADDRESS LOW +Z280_DMA3_SRCH .EQU $1B ; DMA3 SOURCE ADDRESS HIGH +Z280_DMA3_CNT .EQU $1C ; DMA3 COUNT +Z280_DMA3_TDR .EQU $1D ; DMA3 TRANSACTION DESCRIPTION REG +; +; Z280 PAGE $FE REGSISTER ADDRESSES +; +Z280_UARTCFG .EQU $10 ; UART CONFIG REG +Z280_UARTXCTL .EQU $12 ; UART TRANSMIT CONTROL/STATUS REG +Z280_UARTRCTL .EQU $14 ; UART RECEIVE CONTROL/STATUS REG +Z280_UARTRECV .EQU $16 ; UART RECEIVE DATA REG +Z280_UARTXMIT .EQU $18 ; UART TRANSMIT DATA REG + +; +Z280_CT0_CFG .EQU $E0 ; COUNTER/TIMER 0 CONFIG REG +Z280_CT0_CMDST .EQU $E1 ; COUNTER/TIMER 0 COMMAND/STATUS REG +Z280_CT0_TC .EQU $E2 ; COUNTER/TIMER 0 TIME CONSTANT +Z280_CT0_CT .EQU $E3 ; COUNTER/TIMER 0 COUNT TIME +; +Z280_CT1_CFG .EQU $E8 ; COUNTER/TIMER 1 CONFIG REG +Z280_CT1_CMDST .EQU $E9 ; COUNTER/TIMER 1 COMMAND/STATUS REG +Z280_CT1_TC .EQU $EA ; COUNTER/TIMER 1 TIME CONSTANT +Z280_CT1_CT .EQU $EB ; COUNTER/TIMER 1 COUNT TIME +; +Z280_CT2_CFG .EQU $F8 ; COUNTER/TIMER 2 CONFIG REG +Z280_CT2_CMDST .EQU $F9 ; COUNTER/TIMER 2 COMMAND/STATUS REG +Z280_CT2_TC .EQU $FA ; COUNTER/TIMER 2 TIME CONSTANT +Z280_CT2_CT .EQU $FB ; COUNTER/TIMER 2 COUNT TIME + diff --git a/Source/HBIOS/z2u.asm b/Source/HBIOS/z2u.asm new file mode 100644 index 00000000..040ab5cd --- /dev/null +++ b/Source/HBIOS/z2u.asm @@ -0,0 +1,669 @@ +; +;================================================================================================== +; Z280 UART DRIVER (Z280 BUILT-IN UART) +;================================================================================================== +; +; SETUP PARAMETER WORD: +; +-------+---+-------------------+ +---+---+-----------+---+-------+ +; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 | +; +-------+---+---+---------------+ ----+---+-----------+---+-------+ +; F E D C B A 9 8 7 6 5 4 3 2 1 0 +; -- MSB (D REGISTER) -- -- LSB (E REGISTER) -- +; +; CONFIG ($FE__10): +; 7 6 5 4 3 2 1 0 +; 1 1 0 0 0 0 1 0 DEFAULT VALUES +; | | | | | | | | +; | | | | | | | | +; | | | | | | | +-- LB: LOOP BACK ENABLE +; | | | | | + +---- CR: CLOCK RATE +; | | | | +-------- CS: CLOCK SELECT +; | | | +---------- E/O: EVEN/ODD +; | | +------------ P: PARITY +; + +-------------- B/C: BITS PER CHARACTER +; +; TRANSMITTER CONTROL/STATUS REGISTER ($FE__12) +; 7 6 5 4 3 2 1 0 +; 1 0 0 0 0 0 0 0 DEFAULT VALUES +; | | | | | | | | +; | | | | | | | +-- BE: BUFFER EMPTY +; | | | | | | +---- VAL: VALUE +; | | | | | +------ FRC: FORCE CHARACTER +; | | | | +-------- BRK: SEND BREAK +; | | | +---------- SB: STOP BITS +; | | +------------ 0: RESERVED (SET TO 0) +; | +-------------- IE: XMIT INT ENBABLE +; +---------------- EN: TRANSMITTER ENABLE +; +; RECEIVER CONTROL/STATUS REGISTER ($FE__14) +; 7 6 5 4 3 2 1 0 +; 1 0 0 0 0 0 0 0 DEFAULT VALUES +; | | | | | | | | +; | | | | | | | +-- ERR: LOGICAL OR OF (OVE, PE, FE) +; | | | | | | +---- OVE: OVERRUN ERROR +; | | | | | +------ PE: PARITY ERROR +; | | | | +-------- FE: FRAMING ERROR +; | | | +---------- CA: RECEIVE CHAR AVAILABLE +; | | +------------ 0: RESERVED (SET TO 0) +; | +-------------- IE: RECEIVER INT ENBABLE +; +---------------- EN: RECEIVER ENABLE +; +; INTERRUPT DRIVEN PROCESSING IS ONLY USED WHEN THE SYSTEM IS IN +; INTERRUPT MODE 3. THIS IS BECAUSE THE BUILT-IN UART *ALWAYS* USES +; MODE 3 PROCESSING. SINCE MODE 3 PROCESSING REQUIRES THE MODE 3 +; INTERRUPT VECTOR TABLE WHICH IS LARGE AND WON'T FIT WELL IN HIGH +; RAM, IT IS IMPRACTICAL TO IMPLEMENT ANY INTERRUPT DRIVEN PROCESSING +; UNLESS FULL BLOWN INTERRUPT MODE 3 W/ NATIVE MEMORY MANAGEMENT +; IS BEING USED. +; +;Z2U_BUFSZ .EQU 32 ; RECEIVE RING BUFFER SIZE +Z2U_BUFSZ .EQU 128 ; RECEIVE RING BUFFER SIZE +; +Z2U_NONE .EQU 0 ; NOT PRESENT +Z2U_PRESENT .EQU 1 ; PRESENT +; +; +; +Z2U_PREINIT: +; +; SETUP THE DISPATCH TABLE ENTRIES +; NOTE: INTS WILL BE DISABLED WHEN PREINIT IS CALLED AND THEY MUST REMAIN +; DISABLED. +; + LD B,Z2U_CFGCNT ; LOOP CONTROL + XOR A ; ZERO TO ACCUM + LD (Z2U_DEV),A ; CURRENT DEVICE NUMBER + LD IY,Z2U_CFG ; POINT TO START OF CFG TABLE +Z2U_PREINIT0: + PUSH BC ; SAVE LOOP CONTROL + CALL Z2U_INITUNIT ; HAND OFF TO GENERIC INIT CODE + POP BC ; RESTORE LOOP CONTROL +; + LD A,(IY+1) ; GET THE Z280 UART TYPE DETECTED + OR A ; SET FLAGS + JR Z,Z2U_PREINIT2 ; SKIP IT IF NOTHING FOUND +; + PUSH BC ; SAVE LOOP CONTROL + PUSH IY ; CFG ENTRY ADDRESS + POP DE ; ... TO DE + LD BC,Z2U_FNTBL ; BC := FUNCTION TABLE ADDRESS + CALL NZ,CIO_ADDENT ; ADD ENTRY IF Z2U FOUND, BC:DE + POP BC ; RESTORE LOOP CONTROL +; +Z2U_PREINIT2: + LD DE,Z2U_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,DE ; BUMP IY TO NEXT ENTRY + DJNZ Z2U_PREINIT0 ; LOOP UNTIL DONE +; +#IF (INTMODE == 3) + ; SETUP INT VECTORS AS APPROPRIATE + LD A,(Z2U_DEV) ; GET DEVICE COUNT + OR A ; SET FLAGS + JR Z,Z2U_PREINIT3 ; IF ZERO, NO Z2U DEVICES, ABORT +; + LD HL,Z2U_INT ; GET INT VECTOR + LD (Z280_IVT+$36),HL ; SET IT +#ENDIF +; +Z2U_PREINIT3: + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; Z280 UART INITIALIZATION ROUTINE +; +Z2U_INITUNIT: + CALL Z2U_DETECT ; DETERMINE Z280 UART TYPE + LD (IY+1),A ; SAVE IN CONFIG TABLE + OR A ; SET FLAGS + RET Z ; ABORT IF NOTHING THERE + + ; UPDATE WORKING Z280 UART DEVICE NUM + LD HL,Z2U_DEV ; POINT TO CURRENT UART DEVICE NUM + LD A,(HL) ; PUT IN ACCUM + INC (HL) ; INCREMENT IT (FOR NEXT LOOP) + LD (IY),A ; UPDATE UNIT NUM +; + ; IT IS EASY TO SPECIFY A SERIAL CONFIG THAT CANNOT BE IMPLEMENTED + ; DUE TO THE CONSTRAINTS OF THE Z280 UART. HERE WE FORCE A GENERIC + ; FAILSAFE CONFIG ONTO THE CHANNEL. IF THE SUBSEQUENT "REAL" + ; CONFIG FAILS, AT LEAST THE CHIP WILL BE ABLE TO SPIT DATA OUT + ; AT A RATIONAL BAUD/DATA/PARITY/STOP CONFIG. + CALL Z2U_INITSAFE +; + ; SET DEFAULT CONFIG + LD DE,-1 ; LEAVE CONFIG ALONE + ; CALL INITDEV TO IMPLEMENT CONFIG, BUT NOTE THAT WE CALL + ; THE INITDEVX ENTRY POINT THAT DOES NOT ENABLE/DISABLE INTS! + JP Z2U_INITDEVX ; IMPLEMENT IT AND RETURN +; +; +; +Z2U_INIT: + LD B,Z2U_CFGCNT ; COUNT OF POSSIBLE Z2U UNITS + LD IY,Z2U_CFG ; POINT TO START OF CFG TABLE +Z2U_INIT1: + PUSH BC ; SAVE LOOP CONTROL + LD A,(IY+1) ; GET Z2U TYPE + OR A ; SET FLAGS + CALL NZ,Z2U_PRTCFG ; PRINT IF NOT ZERO + POP BC ; RESTORE LOOP CONTROL + LD DE,Z2U_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,DE ; BUMP IY TO NEXT ENTRY + DJNZ Z2U_INIT1 ; LOOP TILL DONE +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; RECEIVE INTERRUPT HANDLER +; +#IF (INTMODE == 3) +; +; INT ENTRY POINT +; +Z2U_INT: + ; DISCARD REASON CODE + INC SP + INC SP +; + ; SAVE REGISTERS + PUSH AF + PUSH BC + PUSH DE + PUSH HL +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; CHECK TO SEE IF SOMETHING IS ACTUALLY THERE + IN A,(Z280_UARTRCTL) ; GET STATUS + AND $10 ; ISOLATE CHAR AVAILABLE BIT + JR Z,Z2U_INTRCV4 ; IF NOT, BAIL OUT +; +Z2U_INTRCV1: + ; RECEIVE CHARACTER INTO BUFFER + IN A,(Z280_UARTRECV) ; GET A BYTE + LD B,A ; SAVE BYTE READ + LD HL,Z2U0_RCVBUF ; SET HL TO START OF BUFFER STRUCT + LD A,(HL) ; GET COUNT + CP Z2U_BUFSZ ; COMPARE TO BUFFER SIZE + JR Z,Z2U_INTRCV4 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED + INC A ; INCREMENT THE COUNT + LD (HL),A ; AND SAVE IT + ;CP Z2U_BUFSZ / 2 ; BUFFER GETTING FULL? + ;JR NZ,Z2U_INTRCV2 ; IF NOT, BYPASS CLEARING RTS + ; THIS IS WHERE WE SHOULD DEASSERT RTS, BUT THE Z2U HAS NONE +Z2U_INTRCV2: + INC HL ; HL NOW HAS ADR OF HEAD PTR + PUSH HL ; SAVE ADR OF HEAD PTR + ;LD A,(HL) ; DEREFERENCE HL + ;INC HL + ;LD H,(HL) + ;LD L,A ; HL IS NOW ACTUAL HEAD PTR + .DB $ED,$26 ; LD HL,(HL) ; DEREFERENCE HL, HL IS NOW ACTUAL HEAD PTR + LD (HL),B ; SAVE CHARACTER RECEIVED IN BUFFER AT HEAD + INC HL ; BUMP HEAD POINTER + POP DE ; RECOVER ADR OF HEAD PTR + LD A,L ; GET LOW BYTE OF HEAD PTR + SUB Z2U_BUFSZ+4 ; SUBTRACT SIZE OF BUFFER AND POINTER + CP E ; IF EQUAL TO START, HEAD PTR IS PAST BUF END + JR NZ,Z2U_INTRCV3 ; IF NOT, BYPASS + LD H,D ; SET HL TO + LD L,E ; ... HEAD PTR ADR + INC HL ; BUMP PAST HEAD PTR + INC HL + INC HL + INC HL ; ... SO HL NOW HAS ADR OF ACTUAL BUFFER START +Z2U_INTRCV3: + EX DE,HL ; DE := HEAD PTR VAL, HL := ADR OF HEAD PTR + ;LD (HL),E ; SAVE UPDATED HEAD PTR + ;INC HL + ;LD (HL),D + .DB $ED,$1E ;LD (HL),DE ; SAVE UPDATED HEAD PTR + + ; CHECK FOR MORE PENDING... + IN A,(Z280_UARTRCTL) ; GET STATUS + AND $10 ; ISOLATE CHAR AVAILABLE BIT + JR NZ,Z2U_INTRCV1 +; +Z2U_INTRCV4: + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; RESTORE REGISTERS + POP HL + POP DE + POP BC + POP AF +; + .DB $ED,$55 ; RETIL +#ENDIF +; +; DRIVER FUNCTION TABLE +; +Z2U_FNTBL: + .DW Z2U_IN + .DW Z2U_OUT + .DW Z2U_IST + .DW Z2U_OST + .DW Z2U_INITDEV + .DW Z2U_QUERY + .DW Z2U_DEVICE +#IF (($ - Z2U_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID Z2U FUNCTION TABLE ***\n" +#ENDIF +; +#IF (INTMODE < 3) +; +Z2U_IN: + CALL Z2U_IST ; CHECK FOR CHAR READY + JR Z,Z2U_IN ; IF NOT, LOOP +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; GET CHAR + IN A,(Z280_UARTRECV) ; GET A BYTE + LD E,A ; PUT IN E FOR RETURN +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +#ELSE +; +Z2U_IN: + CALL Z2U_IST ; SEE IF CHAR AVAILABLE + JR Z,Z2U_IN ; LOOP UNTIL SO + HB_DI ; AVOID COLLISION WITH INT HANDLER + LD L,(IY+6) ; SET HL TO + LD H,(IY+7) ; ... START OF BUFFER STRUCT + LD A,(HL) ; GET COUNT + DEC A ; DECREMENT COUNT + LD (HL),A ; SAVE UPDATED COUNT + ; THIS IS WHERE WE SHOULD ASSERT RTS, BUT THE Z2U HAS NONE +Z2U_IN1: + INC HL ; HL := ADR OF TAIL PTR + INC HL ; " + INC HL ; " + PUSH HL ; SAVE ADR OF TAIL PTR + LD A,(HL) ; DEREFERENCE HL + INC HL + LD H,(HL) + LD L,A ; HL IS NOW ACTUAL TAIL PTR + LD C,(HL) ; C := CHAR TO BE RETURNED + INC HL ; BUMP TAIL PTR + POP DE ; RECOVER ADR OF TAIL PTR + LD A,L ; GET LOW BYTE OF TAIL PTR + SUB Z2U_BUFSZ+2 ; SUBTRACT SIZE OF BUFFER AND POINTER + CP E ; IF EQUAL TO START, TAIL PTR IS PAST BUF END + JR NZ,Z2U_IN2 ; IF NOT, BYPASS + LD H,D ; SET HL TO + LD L,E ; ... TAIL PTR ADR + INC HL ; BUMP PAST TAIL PTR + INC HL ; ... SO HL NOW HAS ADR OF ACTUAL BUFFER START +Z2U_IN2: + EX DE,HL ; DE := TAIL PTR VAL, HL := ADR OF TAIL PTR + LD (HL),E ; SAVE UPDATED TAIL PTR + INC HL ; " + LD (HL),D ; " + LD E,C ; MOVE CHAR TO RETURN TO E + HB_EI ; INTERRUPTS OK AGAIN + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +#ENDIF +; +; +; +Z2U_OUT: + CALL Z2U_OST ; CHECK IF OUTPUT REGISTER READY + JR Z,Z2U_OUT ; LOOP UNTIL SO +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; WRITE CHAR + LD A,E ; BYTE TO A + OUT (Z280_UARTXMIT),A ; SEND IT +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; +; +#IF (INTMODE < 3) +; +Z2U_IST: +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; GET RECEIVE STATUS + IN A,(Z280_UARTRCTL) ; GET STATUS + AND $10 ; ISOLATE CHAR AVAILABLE BIT +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + OR A ; SET FLAGS + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + RET +; +#ELSE +; +Z2U_IST: + LD L,(IY+6) ; GET ADDRESS + LD H,(IY+7) ; ... OF RECEIVE BUFFER + LD A,(HL) ; BUFFER UTILIZATION COUNT + OR A ; SET FLAGS + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + RET ; DONE +; +#ENDIF +; +; +; +Z2U_OST: +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; GET TRANSMIT STATUS + IN A,(Z280_UARTXCTL) ; GET STATUS +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; CHECK FOR CHAR AVAILABLE + AND $01 ; ISOLATE CHAR AVAILABLE BIT + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + RET ; DONE +; +; AT INITIALIZATION THE SETUP PARAMETER WORD IS TRANSLATED TO THE FORMAT +; REQUIRED BY THE Z2U AND STORED IN A PORT/REGISTER INITIALIZATION TABLE, +; WHICH IS THEN LOADED INTO THE Z2U. +; +; NOTE THAT THERE ARE TWO ENTRY POINTS. INITDEV WILL DISABLE/ENABLE INTS +; AND INITDEVX WILL NOT. THIS IS DONE SO THAT THE PREINIT ROUTINE ABOVE +; CAN AVOID ENABLING/DISABLING INTS. +; +Z2U_INITDEV: + HB_DI ; DISABLE INTS + CALL Z2U_INITDEVX ; DO THE WORK + HB_EI ; INTS BACK ON + RET ; DONE +; +Z2U_INITSAFE: + LD A,%11000010 ; 8N0, DIV 16, NO C/T + LD (Z2U_CFGREG),A ; SAVE IT + JR Z2U_INITDEV8 ; DO IT +; +Z2U_INITDEVX: + ; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT) + LD A,D ; TEST DE FOR + AND E ; ... VALUE OF -1 + INC A ; ... SO Z SET IF -1 + JR NZ,Z2U_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG +; + ; LOAD EXISTING CONFIG TO REINIT + LD E,(IY+4) ; LOW BYTE + LD D,(IY+5) ; HIGH BYTE +; +Z2U_INITDEV1: + LD (Z2U_NEWCFG),DE ; SAVE NEW CONFIG + LD A,D ; HIWORD OF CONFIG + AND $1F ; ISOLATE BAUD RATE + PUSH AF +; + LD DE,Z2UOSC >> 16 ; BAUD OSC HI WORD + LD HL,Z2UOSC & $FFFF ; BAUD OSC LO WORD + LD C,75 ; BAUD RATE ENCODE CONSTANT + CALL ENCODE ; C = ENCODED OSC + POP DE ; D = UART OSC + JP NZ,Z2U_INITFAIL ; HANDLE ENCODE FAILURE + LD A,C ; TO A + SUB D ; DIV W/ SUB OF SQUARES + ; REG A NOW HAS ENCODED BAUD RATE DIVISOR +; + PUSH AF ; SAVE IT + AND $0F ; ISOLATE 2'S POWER +; + ; Z280 UART CAN USE 16, 32, OR 64 AS BAUD RATE DIVISOR + ; SET E TO IMPLEMENT WHAT WE CAN + LD E,%11000000 ; 8N0, DIV 1, NO C/T + ;JR Z2U_INITDEV2 ; *DEBUG* + CP 4 ; DIV 16 POSSIBLE? + JR C,Z2U_INITDEV2 ; IF NOT, SKIP AHEAD + LD E,%11000010 ; 8N0, DIV 16, NO C/T + SUB 4 ; REFLECT IN TGT DIVISOR + CP 1 ; DIV 32 POSSIBLE? + JR C,Z2U_INITDEV2 ; IF NOT, SKIP AHEAD + LD E,%11000100 ; 8N0, DIV 32, NO C/T + DEC A ; REFLECT IN TGT DIVISOR + CP 1 ; DIV 64 POSSIBLE? + JR C,Z2U_INITDEV2 ; IF NOT, SKIP AHEAD + LD E,%11000110 ; 8N0, DIV 64, NO C/T + DEC A +; +Z2U_INITDEV2: + LD D,A ; 2'S POWER TO D + POP AF ; RECOVER ORIGINAL VALUE + AND $F0 ; MASK OFF ORIG 2'S POWER + OR D ; COMBINE + ;CALL PRTHEXBYTE ; *DEBUG* + PUSH AF ; RESAVE IT + LD A,E ; GET Z280 UART CONFIG REG VAL + LD (Z2U_CFGREG),A ; SAVE CONFIG REG VALUE FOR LATER + POP AF ; RECOVER REMAINING ENCODED DIVISOR + LD L,A ; INTO L + LD H,0 ; H MUST BE ZERO + LD DE,1 ; RATIO, SO NO CONSTANT + CALL DECODE ; DECODE INTO DE:HL + ;LD HL,626 ; *DEBUG* + JR NZ,Z2U_INITFAIL ; HANDLE FAILURE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXWORDHL ; *DEBUG* +; + ; SAVE CONFIG PERMANENTLY NOW + LD DE,(Z2U_NEWCFG) ; GET NEW CONFIG BACK + LD (IY+4),E ; SAVE LOW WORD + LD (IY+5),D ; SAVE HI WORD +; +Z2U_INITDEV8: + ; START BY SELECTING I/O PAGE $FE + PUSH HL ; SAVE HL + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL + POP HL ; RESTORE HL +; + DEC HL ; ADJUST FOR T/C + LD A,H ; TEST FOR + OR L ; ... ZERO + JR Z,Z2U_INITDEV9 ; IF ZERO, SKIP C/T +; + ; PROGRAM C/T 1 +#IF Z2UOSCEXT + LD A,%10001100 ; CONFIG: C, RE, COUNTER +#ELSE + LD A,%10001000 ; CONFIG: C, RE, COUNTER +#ENDIF + OUT (Z280_CT1_CFG),A ; SET C/T 1 + LD C,Z280_CT1_TC ; SET C/T 1 FROM HL + .DB $ED,$BF ; OUTW (C),HL + LD C,Z280_CT1_CT ; SET C/T 1 FROM HL + .DB $ED,$BF ; OUTW (C),HL + LD A,%11100000 ; CMD: EN, GT, TG + OUT (Z280_CT1_CMDST),A ; SET C/T 1 +; + ; MODIFY CFG REG VALUE TO USE C/T + LD A,(Z2U_CFGREG) ; CONFIG VALUE + SET 3,A ; SET C/T USAGE BIT + LD (Z2U_CFGREG),A ; SAVE IT +; +Z2U_INITDEV9: + ; PROGRAM THE UART + LD A,(Z2U_CFGREG) ; CONFIG VALUE + OUT (Z280_UARTCFG),A ; SET CONFIG REGISTER + LD A,%10000000 ; ENABLE, NO INTS, 1 STOP BITS + OUT (Z280_UARTXCTL),A ; SET XMIT CTL REGISTER +#IF (INTMODE == 3) + LD A,%11000000 ; ENABLE W/ RCV INTS +#ELSE + LD A,%10000000 ; ENABLE, NO RCV INTS +#ENDIF + OUT (Z280_UARTRCTL),A ; SET RCV CTL REGISTER +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; +#IF (INTMODE == 3) +; + ; RESET THE RECEIVE BUFFER + LD E,(IY+6) + LD D,(IY+7) ; DE := _CNT + XOR A ; A := 0 + LD (DE),A ; _CNT = 0 + INC DE ; DE := ADR OF _HD + PUSH DE ; SAVE IT + INC DE + INC DE + INC DE + INC DE ; DE := ADR OF _BUF + POP HL ; HL := ADR OF _HD + LD (HL),E + INC HL + LD (HL),D ; _HD := _BUF + INC HL + LD (HL),E + INC HL + LD (HL),D ; _TL := _BUF +; +#ENDIF +; + ; RETURN SUCCESS + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +Z2U_INITFAIL: + OR $FF ; SIGNAL ERROR + RET ; AND DONE +; +; +; +Z2U_QUERY: + LD E,(IY+4) ; FIRST CONFIG BYTE TO E + LD D,(IY+5) ; SECOND CONFIG BYTE TO D + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; +; +Z2U_DEVICE: + LD D,CIODEV_Z2U ; D := DEVICE TYPE + LD E,(IY) ; E := PHYSICAL UNIT + LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+3) ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; +; Z280 UART DETECTION ROUTINE +; ALWAYS PRESENT, JUST SAY SO. +; +Z2U_DETECT: + LD A,Z2U_PRESENT ; PRESENT + RET +; +; +; +Z2U_PRTCFG: + ; ANNOUNCE PORT + CALL NEWLINE ; FORMATTING + PRTS("Z2U$") ; FORMATTING + LD A,(IY) ; DEVICE NUM + CALL PRTDECB ; PRINT DEVICE NUM + PRTS(": IO=0x$") ; FORMATTING + LD A,(IY+3) ; GET BASE PORT + CALL PRTHEXBYTE ; PRINT BASE PORT +; + ; ALL DONE IF NO Z2U WAS DETECTED + LD A,(IY+1) ; GET Z2U TYPE BYTE + OR A ; SET FLAGS + RET Z ; IF ZERO, NOT PRESENT +; + PRTS(" MODE=$") ; FORMATTING + LD E,(IY+4) ; LOAD CONFIG + LD D,(IY+5) ; ... WORD TO DE + CALL PS_PRTSC0 ; PRINT CONFIG +; + XOR A + RET +; +; WORKING VARIABLES +; +Z2U_DEV .DB 0 ; DEVICE NUM USED DURING INIT +Z2U_CFGREG .DB 0 ; VALUE TO PROGRAM CFG REG +Z2U_NEWCFG .DW 0 ; TEMP STORE FOR NEW CFG +; +#IF (INTMODE < 3) +; +Z2U0_RCVBUF .EQU 0 +; +#ELSE +; +; RECEIVE BUFFERS +; +Z2U0_RCVBUF: +Z2U0_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER +Z2U0_HD .DW Z2U0_BUF ; BUFFER HEAD POINTER +Z2U0_TL .DW Z2U0_BUF ; BUFFER TAIL POINTER +Z2U0_BUF .FILL Z2U_BUFSZ,0 ; RECEIVE RING BUFFER +Z2U0_BUFEND .EQU $ ; END OF BUFFER +Z2U0_BUFSZ .EQU $ - Z2U0_BUF ; SIZE OF RING BUFFER +; +#ENDIF +; +; Z2U PORT TABLE +; +Z2U_CFG: +; +Z2U0_CFG: + ; Z2U CONFIG + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; Z280 UART TYPE (SET DURING INIT) + .DB 0 ; MODULE ID + .DB Z2U0BASE ; BASE PORT + .DW Z2U0CFG ; LINE CONFIGURATION + .DW Z2U0_RCVBUF ; POINTER TO RCV BUFFER STRUCT +; +Z2U_CFGSIZ .EQU $ - Z2U_CFG ; SIZE OF ONE CFG TABLE ENTRY +; +Z2U_CFGCNT .EQU ($ - Z2U_CFG) / Z2U_CFGSIZ diff --git a/Source/Images/Build.cmd b/Source/Images/Build.cmd index 2305cc74..78efeccd 100644 --- a/Source/Images/Build.cmd +++ b/Source/Images/Build.cmd @@ -4,25 +4,43 @@ setlocal echo. echo Building Floppy Disk Images... echo. -call BuildFD.cmd cpm22 ..\cpm22\cpm_wbw.sys -call BuildFD.cmd zsdos ..\zsdos\zsys_wbw.sys -call BuildFD.cmd nzcom ..\zsdos\zsys_wbw.sys -call BuildFD.cmd cpm3 ..\cpm3\cpmldr.sys -call BuildFD.cmd zpm3 ..\cpm3\cpmldr.sys -call BuildFD.cmd ws4 +call BuildDisk.cmd cpm22 wbw_fd144 ..\cpm22\cpm_wbw.sys +call BuildDisk.cmd zsdos wbw_fd144 ..\zsdos\zsys_wbw.sys +call BuildDisk.cmd nzcom wbw_fd144 ..\zsdos\zsys_wbw.sys +call BuildDisk.cmd cpm3 wbw_fd144 ..\cpm3\cpmldr.sys +call BuildDisk.cmd zpm3 wbw_fd144 ..\cpm3\cpmldr.sys +call BuildDisk.cmd ws4 wbw_fd144 echo. -echo Building Hard Disk Images... +echo Building Hard Disk Images (512 directory entry format)... echo. -call BuildHD.cmd cpm22 ..\cpm22\cpm_wbw.sys -call BuildHD.cmd zsdos ..\zsdos\zsys_wbw.sys -call BuildHD.cmd nzcom ..\zsdos\zsys_wbw.sys -call BuildHD.cmd cpm3 ..\cpm3\cpmldr.sys -call BuildHD.cmd zpm3 ..\cpm3\cpmldr.sys -call BuildHD.cmd ws4 +call BuildDisk.cmd cpm22 wbw_hd512 ..\cpm22\cpm_wbw.sys +call BuildDisk.cmd zsdos wbw_hd512 ..\zsdos\zsys_wbw.sys +call BuildDisk.cmd nzcom wbw_hd512 ..\zsdos\zsys_wbw.sys +call BuildDisk.cmd cpm3 wbw_hd512 ..\cpm3\cpmldr.sys +call BuildDisk.cmd zpm3 wbw_hd512 ..\cpm3\cpmldr.sys +call BuildDisk.cmd ws4 wbw_hd512 -if exist ..\BPBIOS\bpbio-ww.rel call BuildHD.cmd bp +if exist ..\BPBIOS\bpbio-ww.rel call BuildDisk.cmd bp wbw_hd512 echo. -echo Building Combo Disk Image... -copy /b ..\..\Binary\hd_cpm22.img + ..\..\Binary\hd_zsdos.img + ..\..\Binary\hd_nzcom.img + ..\..\Binary\hd_cpm3.img + ..\..\Binary\hd_zpm3.img + ..\..\Binary\hd_ws4.img ..\..\Binary\hd_combo.img +echo Building Combo Disk (512 directory entry format) Image... +copy /b ..\..\Binary\hd512_cpm22.img + ..\..\Binary\hd512_zsdos.img + ..\..\Binary\hd512_nzcom.img + ..\..\Binary\hd512_cpm3.img + ..\..\Binary\hd512_zpm3.img + ..\..\Binary\hd512_ws4.img ..\..\Binary\hd512_combo.img + +echo. +echo Building Hard Disk Images (1024 directory entry format)... +echo. +call BuildDisk.cmd cpm22 wbw_hd1024 ..\cpm22\cpm_wbw.sys +call BuildDisk.cmd zsdos wbw_hd1024 ..\zsdos\zsys_wbw.sys +call BuildDisk.cmd nzcom wbw_hd1024 ..\zsdos\zsys_wbw.sys +call BuildDisk.cmd cpm3 wbw_hd1024 ..\cpm3\cpmldr.sys +call BuildDisk.cmd zpm3 wbw_hd1024 ..\cpm3\cpmldr.sys +call BuildDisk.cmd ws4 wbw_hd1024 + +if exist ..\BPBIOS\bpbio-ww.rel call BuildDisk.cmd bp wbw_hd1024 + +copy hd1024_prefix.dat ..\..\Binary\ + +echo. +echo Building Combo Disk (1024 directory entry format) Image... +copy /b hd1024_prefix.dat + ..\..\Binary\hd1024_cpm22.img + ..\..\Binary\hd1024_zsdos.img + ..\..\Binary\hd1024_nzcom.img + ..\..\Binary\hd1024_cpm3.img + ..\..\Binary\hd1024_zpm3.img + ..\..\Binary\hd1024_ws4.img ..\..\Binary\hd1024_combo.img diff --git a/Source/Images/BuildDisk.cmd b/Source/Images/BuildDisk.cmd new file mode 100644 index 00000000..d280c1fd --- /dev/null +++ b/Source/Images/BuildDisk.cmd @@ -0,0 +1 @@ +@PowerShell -ExecutionPolicy Unrestricted .\BuildDisk.ps1 %* \ No newline at end of file diff --git a/Source/Images/BuildDisk.ps1 b/Source/Images/BuildDisk.ps1 new file mode 100644 index 00000000..22e6b971 --- /dev/null +++ b/Source/Images/BuildDisk.ps1 @@ -0,0 +1,95 @@ +Param($Disk, $Format="", $SysFile="") + +$ErrorAction = 'Stop' + +$CpmToolsPath = '../../Tools/cpmtools' + +$env:PATH = $CpmToolsPath + ';' + $env:PATH + +if ($Format.Length -eq 0) +{ + Write-Error "No disk format specified!" -ErrorAction Stop + return +} + +switch ($Format) +{ + "wbw_fd144" + { + # 1.44MB Floppy Disk + $Desc = "1.44MB Floppy Disk" + $ImgFile = "fd144_${Disk}.img" + $MediaID = 6 + $Size = 1440KB + } + + "wbw_hd512" + { + # 512 Directory Entry Hard Disk Format + $Desc = "Hard Disk (512 directory entry format)" + $ImgFile = "hd512_${Disk}.img" + $MediaID = 4 + $Size = 8MB + 128KB + } + + "wbw_hd1024" + { + # 1024 Directory Entry Hard Disk Format + $Desc = "Hard Disk (1024 directory entry format)" + $ImgFile = "hd1024_${Disk}.img" + $MediaID = 10 + $Size = 8MB + } +} + +if (-not (Test-Path("d_${Disk}/"))) +{ + Write-Error "Source directory d_${Disk} for disk ${Disk} not found!" -ErrorAction Stop + return +} + +"Generating $Disk $Desc..." + +if ($SysFile.Length -gt 0) + { [byte[]]$SysImg = [System.IO.File]::ReadAllBytes($SysFile) } +else + { [byte[]]$SysImg = @() } + +$Image = ($SysImg + ([byte[]](0xE5) * ($Size - $SysImg.length))) + +# $Image[1410] = 0x4D +# $Image[1411] = 0x49 +# $Image[1412] = 0x44 +# $Image[1413] = $MediaID + +[System.IO.File]::WriteAllBytes($ImgFile, $Image) + +for ($Usr=0; $Usr -lt 16; $Usr++) +{ + if (Test-Path ("d_${Disk}/u${Usr}/*")) + { + $Cmd = "cpmcp -f $Format $ImgFile d_${Disk}/u${Usr}/*.* ${Usr}:" + $Cmd + Invoke-Expression $Cmd + } +} + +if (Test-Path("d_${Disk}.txt")) +{ + foreach($Line in Get-Content "d_${Disk}.txt") + { + $Spec = $Line.Trim() + if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#")) + { + $Cmd = "cpmcp -f $Format $ImgFile ${Spec}" + $Cmd + Invoke-Expression $Cmd + } + } +} + +"Moving image $ImgFile into output directory..." + +Move-Item $ImgFile -Destination "..\..\Binary\" -Force + +return \ No newline at end of file diff --git a/Source/Images/BuildFD.cmd b/Source/Images/BuildFD.cmd deleted file mode 100644 index b251f23e..00000000 --- a/Source/Images/BuildFD.cmd +++ /dev/null @@ -1 +0,0 @@ -@PowerShell -ExecutionPolicy Unrestricted .\BuildFD.ps1 %* \ No newline at end of file diff --git a/Source/Images/BuildFD.ps1 b/Source/Images/BuildFD.ps1 deleted file mode 100644 index f482bc10..00000000 --- a/Source/Images/BuildFD.ps1 +++ /dev/null @@ -1,69 +0,0 @@ -#Param([Parameter(Mandatory)]$Disk, $SysFile="") -Param($Disk, $SysFile="") - -$ErrorAction = 'Stop' - -$ImgFile = "fd_${Disk}.img" -$Fmt = "wbw_fd144" -$Size = 1440KB - -$CpmToolsPath = '../../Tools/cpmtools' - -$env:PATH = $CpmToolsPath + ';' + $env:PATH - -if (-not (Test-Path("d_${Disk}/"))) -{ - "Source directory d_${Disk} for disk ${Disk} not found!" - return -} - -"Generating Floppy Disk ${Disk}..." - -#$Blank = ([string]([char]0xE5)) * $Size -#Set-Content -Value $Blank -NoNewLine -Path $ImgFile -$Blank = ([byte[]](0xE5) * $Size) -[System.IO.File]::WriteAllBytes($ImgFile, $Blank) - -if ($SysFile.Length -gt 0) -{ - "Adding System Image $SysFile..." - #$Sys = Get-Content -Path "$SysFile.sys" -Raw - #$Img = Get-Content -Path $ImgFile -Raw - #$NewImg = $Sys + $Img.SubString($Sys.Length, $Img.Length - $Sys.Length) - #Set-Content -NoNewLine -Path $ImgFile $NewImg - - $Cmd = "mkfs.cpm -f $Fmt -b $SysFile $ImgFile" - $Cmd - Invoke-Expression $Cmd -} - -for ($Usr=0; $Usr -lt 16; $Usr++) -{ - if (Test-Path ("d_${Disk}/u${Usr}/*")) - { - $Cmd = "cpmcp -f $Fmt $ImgFile d_${Disk}/u${Usr}/*.* ${Usr}:" - $Cmd - Invoke-Expression $Cmd - } -} - -if (Test-Path("d_${Disk}.txt")) -{ - foreach($Line in Get-Content "d_${Disk}.txt") - { - $Spec = $Line.Trim() - if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#")) - { - $Cmd = "cpmcp -f $Fmt $ImgFile ${Spec}" - $Cmd - Invoke-Expression $Cmd - } - } -} - -"Moving image $ImgFile into output directory..." - -#&$env:COMSPEC /c move $ImgFile ..\..\Binary\ -Move-Item $ImgFile -Destination "..\..\Binary\" -Force - -return \ No newline at end of file diff --git a/Source/Images/BuildHD.cmd b/Source/Images/BuildHD.cmd deleted file mode 100644 index c7db537e..00000000 --- a/Source/Images/BuildHD.cmd +++ /dev/null @@ -1 +0,0 @@ -@PowerShell -ExecutionPolicy Unrestricted .\BuildHD.ps1 %* \ No newline at end of file diff --git a/Source/Images/BuildHD.ps1 b/Source/Images/BuildHD.ps1 deleted file mode 100644 index eedfa4aa..00000000 --- a/Source/Images/BuildHD.ps1 +++ /dev/null @@ -1,69 +0,0 @@ -#Param([Parameter(Mandatory)]$Disk, $SysFile="") -Param($Disk, $SysFile="") - -$ErrorAction = 'Stop' - -$ImgFile = "hd_${Disk}.img" -$Fmt = "wbw_hd0" -$Size = (128KB * 65) - -$CpmToolsPath = '../../Tools/cpmtools' - -$env:PATH = $CpmToolsPath + ';' + $env:PATH - -if (-not (Test-Path("d_${Disk}/"))) -{ - "Source directory d_${Disk} for disk ${Disk} not found!" - return -} - -"Generating Hard Disk ${Disk}..." - -#$Blank = ([string]([char]0xE5)) * $Size -#Set-Content -Value $Blank -NoNewLine -Path $ImgFile -$Blank = ([byte[]](0xE5) * $Size) -[System.IO.File]::WriteAllBytes($ImgFile, $Blank) - -if ($SysFile.Length -gt 0) -{ - "Adding System Image $SysFile..." - #$Sys = Get-Content -Path "$SysFile.sys" -Raw - #$Img = Get-Content -Path $ImgFile -Raw - #$NewImg = $Sys + $Img.SubString($Sys.Length, $Img.Length - $Sys.Length) - #Set-Content -NoNewLine -Path $ImgFile $NewImg - - $Cmd = "mkfs.cpm -f $Fmt -b $SysFile $ImgFile" - $Cmd - Invoke-Expression $Cmd -} - -for ($Usr=0; $Usr -lt 16; $Usr++) -{ - if (Test-Path ("d_${Disk}/u${Usr}/*")) - { - $Cmd = "cpmcp -f $Fmt $ImgFile d_${Disk}/u${Usr}/*.* ${Usr}:" - $Cmd - Invoke-Expression $Cmd - } -} - -if (Test-Path("d_${Disk}.txt")) -{ - foreach($Line in Get-Content "d_${Disk}.txt") - { - $Spec = $Line.Trim() - if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#")) - { - $Cmd = "cpmcp -f $Fmt $ImgFile ${Spec}" - $Cmd - Invoke-Expression $Cmd - } - } -} - -"Moving image $ImgFile into output directory..." - -#&$env:COMSPEC /c move $ImgFile ..\..\Binary\ -Move-Item $ImgFile -Destination "..\..\Binary\" -Force - -return \ No newline at end of file diff --git a/Source/Images/Common/CLRDIR.COM b/Source/Images/Common/CLRDIR.COM index c6b05cc9..ca65cbed 100644 Binary files a/Source/Images/Common/CLRDIR.COM and b/Source/Images/Common/CLRDIR.COM differ diff --git a/Source/Images/Common/FDISK80.COM b/Source/Images/Common/FDISK80.COM index 0d73cef2..7e862d67 100644 Binary files a/Source/Images/Common/FDISK80.COM and b/Source/Images/Common/FDISK80.COM differ diff --git a/Source/Images/Common/FLASH.COM b/Source/Images/Common/FLASH.COM index 1b7fa64c..c81f9c54 100644 Binary files a/Source/Images/Common/FLASH.COM and b/Source/Images/Common/FLASH.COM differ diff --git a/Source/Images/d_bp/u0/MBASIC.COM b/Source/Images/Common/MBASIC.COM similarity index 100% rename from Source/Images/d_bp/u0/MBASIC.COM rename to Source/Images/Common/MBASIC.COM diff --git a/Source/Images/Makefile b/Source/Images/Makefile index 4832dc37..7df9706f 100644 --- a/Source/Images/Makefile +++ b/Source/Images/Makefile @@ -1,16 +1,27 @@ # -# this makefile subsumes all the work done in Build.cmd, Build{Hd,Fd}.* +# this makefile subsumes all the work done in Build.cmd, BuildDisk.cmd, BuildDisk.ps1 # SYSTEMS = ../CPM22/cpm_wbw.sys ../ZSDOS/zsys_wbw.sys ../CPM3/cpmldr.sys -FDIMGS = fd_cpm22.img fd_zsdos.img fd_nzcom.img \ - fd_cpm3.img fd_zpm3.img fd_ws4.img -HDIMGS = hd_cpm22.img hd_zsdos.img hd_nzcom.img \ - hd_cpm3.img hd_zpm3.img hd_ws4.img -# HDIMGS += hd_bp.img +FDIMGS = fd144_cpm22.img fd144_zsdos.img fd144_nzcom.img \ + fd144_cpm3.img fd144_zpm3.img fd144_ws4.img +HD512IMGS = hd512_cpm22.img hd512_zsdos.img hd512_nzcom.img \ + hd512_cpm3.img hd512_zpm3.img hd512_ws4.img +# HDIMGS += hd512_bp.img +HD1024IMGS = hd1024_cpm22.img hd1024_zsdos.img hd1024_nzcom.img \ + hd1024_cpm3.img hd1024_zpm3.img hd1024_ws4.img +# HD1024IMGS += hd1024_bp.img -OBJECTS = $(FDIMGS) $(HDIMGS) hd_combo.img -OTHERS = blank144 blankhd +HD512PREFIX = +HD1024PREFIX = hd1024_prefix.dat + +OBJECTS = $(FDIMGS) +OBJECTS += $(HD512IMGS) hd512_combo.img $(HD512PREFIX) +OBJECTS += $(HD1024IMGS) hd1024_combo.img $(HD1024PREFIX) + +OTHERS = blank144 blankhd512 blankhd1024 + +NODELETE = $(HD512PREFIX) $(HD1024PREFIX) DEST=../../Binary @@ -19,8 +30,11 @@ include $(TOOLS)/Makefile.inc DIFFPATH = $(DIFFTO)/Binary -hd_combo.img: $(HDIMGS) - cat $(HDIMGS) > $@ +hd512_combo.img: $(HD512PREFIX) $(HD512IMGS) + cat $^ > $@ + +hd1024_combo.img: $(HD1024PREFIX) $(HD1024IMGS) + cat $^ > $@ # # this somewhat impenetrable and fragile code is used to build each of the images @@ -30,27 +44,42 @@ hd_combo.img: $(HDIMGS) # then process the d_{d}.txt file, copying in those files, and finally maybe put # an OS at the start of each image # + +FDSIZE := 1440 + blank144: - @echo Making Blank Floppy of size 1440k - @LANG=en_US.US-ASCII tr '\000' '\345' /dev/null + @echo Making Blank Floppy of size $(FDSIZE)k + @LC_ALL=en_US.US-ASCII tr '\000' '\345' /dev/null +blankhd512: + @echo Making Blank HD512 of size $(HD512SIZE)k + @LC_ALL=en_US.US-ASCII tr '\000' '\345' $$i.ls ; \ - $(BINDIR)/cpmls -i -f $$fmt $(DIFFPATH)/$$i > $$i.diff.ls ; \ - done \ + +clean:: + @rm -f *.ls + +imgdiff: + @for i in $(FDIMGS) $(HD512IMGS) $(HD1024IMGS) ; do \ + echo $$i ; \ + if echo $$i | grep -q ^fd144_ ; then \ + fmt=wbw_fd144 ; \ + fi ; \ + if echo $$i | grep -q ^hd512_ ; then \ + fmt=wbw_hd512 ; \ + fi ; \ + if echo $$i | grep -q ^hd1024_ ; then \ + fmt=wbw_hd1024 ; \ + fi ; \ + $(BINDIR)/cpmls -i -f $$fmt $$i > $$i.ls ; \ + $(BINDIR)/cpmls -i -f $$fmt $(DIFFPATH)/$$i > $$i.diff.ls ; \ + done \ diff --git a/Source/Images/ReadMe.txt b/Source/Images/ReadMe.txt index fb4338e2..3954af2f 100644 --- a/Source/Images/ReadMe.txt +++ b/Source/Images/ReadMe.txt @@ -7,7 +7,7 @@ *********************************************************************** This directory contains a toolset for RomWBW that builds floppy and -hard disk media images that can be used on RomWBW by writing the +hard disk media images that can be used with RomWBW by writing the image to a floppy or hard disk (including CF and SD cards). In summary, CP/M files are placed inside of a pre-defined Windows @@ -47,29 +47,38 @@ structure. The structure is: | . +--> u15 -A given disk is reprsented by a directory named d_xxx where xxx can +A given disk is represented by a directory named d_xxx where xxx can be anything you want. Within the d_xxx directory, the CP/M user -areas are represented by subdirectories names u0 thru u15. The files +areas are represented by subdirectories named u0 thru u15. The files to be placed in the disk image are placed inside of the u0 thru u15 directories depending on which user area you want the file(s) to appear. You do not need to create all of the u## subdirectories, only the ones corresponding to the user areas you want to put files in. -To build the disk images, you run the Build.cmd batch file from a -command prompt. Build.cmd in turn invokes separate scripts to create -the floppy and hard disk images. +To build all the disk images, you run the Build.cmd batch file from a +command prompt. Build.cmd in turn invokes a separate script to create +each floppy and hard disk image. As distributed, you will see that there are several d_ directories -populated with files. If you look at the Build.cmd -script, you will find that the names of each of these directories is -listed. If you want to add a new d_ directory to be converted into a -disk image, you will need to add the name of your new directory to -this list. Note that each d_ directory may be turned into a floppy -image or a hard disk image or both. - +populated with files. If you look at the Build.cmd script, you will +find that the names of each of these directories is listed. If you +want to add a new d_ directory to be converted into a disk image, you +will need to add the name of your new directory to this list. Note +that each d_ directory may be turned into a floppy image or a hard +disk image or both. + At present, the scripts assume that the floppy media is 1.44MB. You will need to modify the scripts if you want to create different media. +The resultant disk images (.img files) can be written to the start of +a disk using your Windows/Linux/Mac computer and will then be usable +in your RomWBW computer. On Windows, you can use Win32DiskImager to +do this (see Tools\Win32DiskImager). On Linux/Mac, you can usee dd. + +WARNING: The hd1024 disk images must be prefixed by the +hd1024_prefix.dat file before being written to your target media. +See the Hard Disk Formats section below for more information. + Building the Images ------------------- @@ -81,23 +90,44 @@ included in the distribution under the Tools directory. Many of the disk images depend upon files that are produced by building the shared components of RomWBW. Prior to running the Build command in the Images directory, you should first -run the BuildShared command in the Source directory. +run the BuildShared command in the Source directory. This produces +several files that are prerequisites for creating the disk images. The scripts are intended to be run from a command prompt. Open a command prompt and navigate to the Images directory. Use the command "Build" to build both the floppy and hard disk images in one run. -You can build a single disk image by running either BuildFD.cmd or -BuildHD.cmd with a single parameter specifying the disk name. +You can build a single disk image by running BuildDisk.cmd: + + BuildDisk [] + +where: + + specifies the disk contents (e.g., "cpm22") + specifies the disk format which must be one of: + - "fd144": 1.44M floppy disk + - "hd512": hard disk with 512 directory entries + - "hd1024": hard disk with 1024 directory entries + optionally specifies a boot system image to place in the + system tracks of the disk (e.g., "..\cpm22\cpm_wbw.sys" + +For example: + + | BuildDisk.cmd cpm22 wbw_hd512 ..\cpm22\cpm_wbw.sys + +will create a hard disk image (512 directory entry format) with the +CP/M 2.2 files from the d_cpm22 directory tree and will place the +CP/M 2.2 system image in the boot system tracks. After completion of the script, the resultant image files are placed -in the Binary directory with names such as fd_xxx.img and hd_xxx.img. +in the Binary directory with names such as fd144_xxx.img, hd512_xxx.img, +and hd1024_xxx.img. Sample output from running Build.cmd is provided at the end of this file. -Be aware that the script always builds the image file from scratch. +Be aware that the script always builds the image files from scratch. It will not update the previous contents. Any contents of a -pre-existing image file will be permanently destroyed. +pre-existing image file will be overwritten. Slices ------ @@ -114,19 +144,72 @@ independent CP/M drives. The disk image creation scripts in this directory will only create 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 +multiple images together (the 1024 directory entry format requires a +prefix file, see below). 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 + | C:\RomWBW\Binary>copy /b hd512_zsdos.img + hd512_ws4.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 concept of slices applies ONLY to hard disks. Floppy disks are +The concept of slices applies only to hard disks. Floppy disks are not large enough to support multiple slices. +Hard Disk Formats +----------------- + +RomWBW supports two hard disk formats: the original format used by +RomWBW with 512 directory entries per slice and a new format with +1024 directory entries per slice. These formats are referred to as +hd512 and hd1024 respectively. You will note that filenames start +with either hd512_ or hd1024_ to indicate the hard disk format. + +WARNING: You **can not** mix the two hard disk formats on one hard +disk device. You can use different formats on different hard disk +devices in a single system though. + +RomWBW determines which of the hard disk formats to use for a given +hard disk device based on whether there is a RomWBW hard disk +partition on the disk containing the slices. If there is no RomWBW +partition, then RomWBW will assume the 512 directory entry format for +all slices and will assume the slices start at the first sector of +the hard disk. If there is a RomWBW partition on the hard disk +device, then RomWBW will assume the 1024 directory entry format for +all slices and will assume the slices are located in the defined +partition. You cannot mix the hard disk formats on a single disk +device. + +WARNNG: The hd1024_xxx.img files **must** be prefixed by a partition +table before being written to your disk media. The hd1024_prefix.dat +file is provided for this. The hd1024_prefix.dat defines the required +partition table. Any number of hd1024 slice images can be +concatenated after the prefix. For example, to make the +hd1024_cpm22.img file ready to write to your media, you would need to +do something like this: + + | C:\RomWBW\Binary>copy /b hd1024_prefix.dat + hd1024_cpm22.img hd_cpm22.img + +and then use the resulting hd_cpm22.img to write to the target media. + +For example, if you wanted to create a 2 slice disk image using the +hd1024 entry format 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 hd1024_prefix.dat + hd1024_zsdos.img + hd1024_ws4.img hd_multi.img + +Since the hd512 format does not utilize a partition, you do not +prefix the hd512_xxx.img files with anything. They are ready to write +to your media as is. + +In general, the hd1024 format is considered the better format to use. +It provides double the directory space and places all slices inside +of a hard disk partition that DOS/Windows should respect as "used" +space. + Disk Images ----------- @@ -134,328 +217,297 @@ The standard RomWBW build process builds the disk images defined in this directory. The resultant images are placed in the Binary directory and are ready to copy to your media. +Additionally, a "combo" disk image is created in both the hd512 and +hd1024 formats that contains a multi-slice image that is handy to +use for initial testing. The combo disk image contains the following +slices: + + | Slice 0: CP/M 2.2 (bootable) + | Slice 1: ZSDOS 1.1 (bootable) + | Slice 2: NZCOM (bootable), requires configuration + | Slice 3: CP/M 3 (bootable) + | Slice 4: ZPM3 (bootable) + | Slice 5: WordStar 4 + A description of the specific image files is found in the file called DiskList.txt in the Binary directory of the distribution. +NOTE: The hd1024_combo.img file is already prefixed with +hd1024_prefix.dat, so you do not need to add the prefix file. It is +ready to write to your media. + Sample Run ---------- Below is sample output from building the hard disk images: C:\Users\Wayne\Projects\RBC\Build\RomWBW\Source\Images>Build.cmd - | : - | : Cleaning... - | : - | : - | : Creating System Images - | : - | ..\bl\bl.bin - | ..\cpm22\os2ccp.bin - | ..\cpm22\os3bdos.bin - | ..\cbios\cbios_wbw.bin - | 1 file(s) copied. - | ..\bl\bl.bin - | ..\cpm22\os2ccp.bin - | ..\cpm22\os3bdos.bin - | ..\cbios\cbios_una.bin + + | Building Floppy Disk Images... + | + | Generating cpm22 1.44MB Floppy Disk... + | cpmcp -f wbw_fd144 fd144_cpm22.img d_cpm22/u0/*.* 0: + | cpmcp -f wbw_fd144 fd144_cpm22.img d_cpm22/u1/*.* 1: + | cpmcp -f wbw_fd144 fd144_cpm22.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_fd144 fd144_cpm22.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_fd144 fd144_cpm22.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_fd144 fd144_cpm22.img ../CPM22/cpm_wbw.sys 0:cpm.sys + | cpmcp -f wbw_fd144 fd144_cpm22.img Common/*.* 0: + | Moving image fd144_cpm22.img into output directory... + | Generating zsdos 1.44MB Floppy Disk... + | cpmcp -f wbw_fd144 fd144_zsdos.img d_zsdos/u0/*.* 0: + | cpmcp -f wbw_fd144 fd144_zsdos.img d_zsdos/u1/*.* 1: + | cpmcp -f wbw_fd144 fd144_zsdos.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_fd144 fd144_zsdos.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_fd144 fd144_zsdos.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_fd144 fd144_zsdos.img ../ZSDOS/zsys_wbw.sys 0:zsys.sys + | cpmcp -f wbw_fd144 fd144_zsdos.img Common/*.* 0: + | Moving image fd144_zsdos.img into output directory... + | Generating nzcom 1.44MB Floppy Disk... + | cpmcp -f wbw_fd144 fd144_nzcom.img d_nzcom/u0/*.* 0: + | cpmcp -f wbw_fd144 fd144_nzcom.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_fd144 fd144_nzcom.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_fd144 fd144_nzcom.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_fd144 fd144_nzcom.img ../CPM22/cpm_wbw.sys 0:cpm.sys + | cpmcp -f wbw_fd144 fd144_nzcom.img ../ZSDOS/zsys_wbw.sys 0:zsys.sys + | cpmcp -f wbw_fd144 fd144_nzcom.img Common/*.* 0: + | Moving image fd144_nzcom.img into output directory... + | Generating cpm3 1.44MB Floppy Disk... + | cpmcp -f wbw_fd144 fd144_cpm3.img d_cpm3/u0/*.* 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/cpmldr.com 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/cpmldr.sys 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/ccp.com 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/gencpm.com 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/genres.dat 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/genbnk.dat 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/bios3.spr 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/bnkbios3.spr 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/bdos3.spr 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/bnkbdos3.spr 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/resbdos3.spr 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/cpm3res.sys 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/cpm3bnk.sys 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/gencpm.dat 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/cpm3.sys 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/readme.1st 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../CPM3/cpm3fix.pat 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_fd144 fd144_cpm3.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_fd144 fd144_cpm3.img Common/*.* 0: + | Moving image fd144_cpm3.img into output directory... + | Generating zpm3 1.44MB Floppy Disk... + | cpmcp -f wbw_fd144 fd144_zpm3.img d_zpm3/u0/*.* 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img d_zpm3/u10/*.* 10: + | cpmcp -f wbw_fd144 fd144_zpm3.img d_zpm3/u14/*.* 14: + | cpmcp -f wbw_fd144 fd144_zpm3.img d_zpm3/u15/*.* 15: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/zpmldr.com 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/zpmldr.sys 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../CPM3/cpmldr.com 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../CPM3/cpmldr.sys 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/autotog.com 15: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/clrhist.com 15: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/setz3.com 15: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/cpm3.sys 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/zccp.com 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/zinstal.zpm 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/startzpm.com 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/makedos.com 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/gencpm.dat 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/bnkbios3.spr 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/bnkbdos3.spr 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../ZPM3/resbdos3.spr 0: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../../Binary/Apps/*.com 15: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_fd144 fd144_zpm3.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_fd144 fd144_zpm3.img Common/*.* 15: + | Moving image fd144_zpm3.img into output directory... + | Generating ws4 1.44MB Floppy Disk... + | cpmcp -f wbw_fd144 fd144_ws4.img d_ws4/u0/*.* 0: + | Moving image fd144_ws4.img into output directory... + | + | Building Hard Disk Images (512 directory entry format)... + | + | Generating cpm22 Hard Disk (512 directory entry format)... + | cpmcp -f wbw_hd512 hd512_cpm22.img d_cpm22/u0/*.* 0: + | cpmcp -f wbw_hd512 hd512_cpm22.img d_cpm22/u1/*.* 1: + | cpmcp -f wbw_hd512 hd512_cpm22.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_hd512 hd512_cpm22.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd512 hd512_cpm22.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd512 hd512_cpm22.img ../CPM22/cpm_wbw.sys 0:cpm.sys + | cpmcp -f wbw_hd512 hd512_cpm22.img Common/*.* 0: + | Moving image hd512_cpm22.img into output directory... + | Generating zsdos Hard Disk (512 directory entry format)... + | cpmcp -f wbw_hd512 hd512_zsdos.img d_zsdos/u0/*.* 0: + | cpmcp -f wbw_hd512 hd512_zsdos.img d_zsdos/u1/*.* 1: + | cpmcp -f wbw_hd512 hd512_zsdos.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_hd512 hd512_zsdos.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd512 hd512_zsdos.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd512 hd512_zsdos.img ../ZSDOS/zsys_wbw.sys 0:zsys.sys + | cpmcp -f wbw_hd512 hd512_zsdos.img Common/*.* 0: + | Moving image hd512_zsdos.img into output directory... + | Generating nzcom Hard Disk (512 directory entry format)... + | cpmcp -f wbw_hd512 hd512_nzcom.img d_nzcom/u0/*.* 0: + | cpmcp -f wbw_hd512 hd512_nzcom.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_hd512 hd512_nzcom.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd512 hd512_nzcom.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd512 hd512_nzcom.img ../CPM22/cpm_wbw.sys 0:cpm.sys + | cpmcp -f wbw_hd512 hd512_nzcom.img ../ZSDOS/zsys_wbw.sys 0:zsys.sys + | cpmcp -f wbw_hd512 hd512_nzcom.img Common/*.* 0: + | Moving image hd512_nzcom.img into output directory... + | Generating cpm3 Hard Disk (512 directory entry format)... + | cpmcp -f wbw_hd512 hd512_cpm3.img d_cpm3/u0/*.* 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/cpmldr.com 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/cpmldr.sys 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/ccp.com 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/gencpm.com 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/genres.dat 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/genbnk.dat 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/bios3.spr 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/bnkbios3.spr 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/bdos3.spr 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/bnkbdos3.spr 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/resbdos3.spr 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/cpm3res.sys 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/cpm3bnk.sys 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/gencpm.dat 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/cpm3.sys 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/readme.1st 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../CPM3/cpm3fix.pat 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd512 hd512_cpm3.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd512 hd512_cpm3.img Common/*.* 0: + | Moving image hd512_cpm3.img into output directory... + | Generating zpm3 Hard Disk (512 directory entry format)... + | cpmcp -f wbw_hd512 hd512_zpm3.img d_zpm3/u0/*.* 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img d_zpm3/u10/*.* 10: + | cpmcp -f wbw_hd512 hd512_zpm3.img d_zpm3/u14/*.* 14: + | cpmcp -f wbw_hd512 hd512_zpm3.img d_zpm3/u15/*.* 15: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/zpmldr.com 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/zpmldr.sys 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../CPM3/cpmldr.com 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../CPM3/cpmldr.sys 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/autotog.com 15: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/clrhist.com 15: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/setz3.com 15: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/cpm3.sys 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/zccp.com 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/zinstal.zpm 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/startzpm.com 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/makedos.com 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/gencpm.dat 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/bnkbios3.spr 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/bnkbdos3.spr 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../ZPM3/resbdos3.spr 0: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../../Binary/Apps/*.com 15: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd512 hd512_zpm3.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd512 hd512_zpm3.img Common/*.* 15: + | Moving image hd512_zpm3.img into output directory... + | Generating ws4 Hard Disk (512 directory entry format)... + | cpmcp -f wbw_hd512 hd512_ws4.img d_ws4/u0/*.* 0: + | Moving image hd512_ws4.img into output directory... + | + | Building Combo Disk (512 directory entry format) Image... + | ..\..\Binary\hd512_cpm22.img + | ..\..\Binary\hd512_zsdos.img + | ..\..\Binary\hd512_nzcom.img + | ..\..\Binary\hd512_cpm3.img + | ..\..\Binary\hd512_zpm3.img + | ..\..\Binary\hd512_ws4.img | 1 file(s) copied. - | ..\bl\bl.bin - | ..\zcpr-dj\zcpr.bin - | ..\zsdos\zsdos.bin - | ..\cbios\cbios_wbw.bin + | + | Building Hard Disk Images (1024 directory entry format)... + | + | Generating cpm22 Hard Disk (1024 directory entry format)... + | cpmcp -f wbw_hd1024 hd1024_cpm22.img d_cpm22/u0/*.* 0: + | cpmcp -f wbw_hd1024 hd1024_cpm22.img d_cpm22/u1/*.* 1: + | cpmcp -f wbw_hd1024 hd1024_cpm22.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_hd1024 hd1024_cpm22.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd1024 hd1024_cpm22.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd1024 hd1024_cpm22.img ../CPM22/cpm_wbw.sys 0:cpm.sys + | cpmcp -f wbw_hd1024 hd1024_cpm22.img Common/*.* 0: + | Moving image hd1024_cpm22.img into output directory... + | Generating zsdos Hard Disk (1024 directory entry format)... + | cpmcp -f wbw_hd1024 hd1024_zsdos.img d_zsdos/u0/*.* 0: + | cpmcp -f wbw_hd1024 hd1024_zsdos.img d_zsdos/u1/*.* 1: + | cpmcp -f wbw_hd1024 hd1024_zsdos.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_hd1024 hd1024_zsdos.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd1024 hd1024_zsdos.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd1024 hd1024_zsdos.img ../ZSDOS/zsys_wbw.sys 0:zsys.sys + | cpmcp -f wbw_hd1024 hd1024_zsdos.img Common/*.* 0: + | Moving image hd1024_zsdos.img into output directory... + | Generating nzcom Hard Disk (1024 directory entry format)... + | cpmcp -f wbw_hd1024 hd1024_nzcom.img d_nzcom/u0/*.* 0: + | cpmcp -f wbw_hd1024 hd1024_nzcom.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_hd1024 hd1024_nzcom.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd1024 hd1024_nzcom.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd1024 hd1024_nzcom.img ../CPM22/cpm_wbw.sys 0:cpm.sys + | cpmcp -f wbw_hd1024 hd1024_nzcom.img ../ZSDOS/zsys_wbw.sys 0:zsys.sys + | cpmcp -f wbw_hd1024 hd1024_nzcom.img Common/*.* 0: + | Moving image hd1024_nzcom.img into output directory... + | Generating cpm3 Hard Disk (1024 directory entry format)... + | cpmcp -f wbw_hd1024 hd1024_cpm3.img d_cpm3/u0/*.* 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/cpmldr.com 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/cpmldr.sys 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/ccp.com 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/gencpm.com 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/genres.dat 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/genbnk.dat 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/bios3.spr 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/bnkbios3.spr 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/bdos3.spr 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/bnkbdos3.spr 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/resbdos3.spr 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/cpm3res.sys 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/cpm3bnk.sys 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/gencpm.dat 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/cpm3.sys 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/readme.1st 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../CPM3/cpm3fix.pat 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../../Binary/Apps/*.com 0: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd1024 hd1024_cpm3.img Common/*.* 0: + | Moving image hd1024_cpm3.img into output directory... + | Generating zpm3 Hard Disk (1024 directory entry format)... + | cpmcp -f wbw_hd1024 hd1024_zpm3.img d_zpm3/u0/*.* 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img d_zpm3/u10/*.* 10: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img d_zpm3/u14/*.* 14: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img d_zpm3/u15/*.* 15: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/zpmldr.com 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/zpmldr.sys 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../CPM3/cpmldr.com 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../CPM3/cpmldr.sys 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/autotog.com 15: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/clrhist.com 15: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/setz3.com 15: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/cpm3.sys 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/zccp.com 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/zinstal.zpm 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/startzpm.com 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/makedos.com 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/gencpm.dat 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/bnkbios3.spr 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/bnkbdos3.spr 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../ZPM3/resbdos3.spr 0: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../../Binary/Apps/*.com 15: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../../Binary/Apps/Tunes/*.pt? 3: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img ../../Binary/Apps/Tunes/*.mym 3: + | cpmcp -f wbw_hd1024 hd1024_zpm3.img Common/*.* 15: + | Moving image hd1024_zpm3.img into output directory... + | Generating ws4 Hard Disk (1024 directory entry format)... + | cpmcp -f wbw_hd1024 hd1024_ws4.img d_ws4/u0/*.* 0: + | Moving image hd1024_ws4.img into output directory... | 1 file(s) copied. - | ..\bl\bl.bin - | ..\zcpr-dj\zcpr.bin - | ..\zsdos\zsdos.bin - | ..\cbios\cbios_una.bin + | + | Building Combo Disk (1024 directory entry format) Image... + | hd1024_prefix.dat + | ..\..\Binary\hd1024_cpm22.img + | ..\..\Binary\hd1024_zsdos.img + | ..\..\Binary\hd1024_nzcom.img + | ..\..\Binary\hd1024_cpm3.img + | ..\..\Binary\hd1024_zpm3.img + | ..\..\Binary\hd1024_ws4.img | 1 file(s) copied. - | : - | : Building Floppy Disk Images... - | : - | Generating Floppy Disk cpm22... - | cpmcp -f wbw_fd144 fd_cpm22.img d_cpm22/u0/*.* 0: - | cpmcp -f wbw_fd144 fd_cpm22.img d_cpm22/u1/*.* 1: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_fd144 fd_cpm22.img ../../Binary/Apps/Tunes/*.* 3: - | Adding System Image cpm_wbw... - | Moving image fd_cpm22.img into output directory... - | 1 file(s) moved. - | Generating Floppy Disk zsdos... - | cpmcp -f wbw_fd144 fd_zsdos.img d_zsdos/u0/*.* 0: - | cpmcp -f wbw_fd144 fd_zsdos.img d_zsdos/u1/*.* 1: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_fd144 fd_zsdos.img ../../Binary/Apps/Tunes/*.* 3: - | Adding System Image zsys_wbw... - | Moving image fd_zsdos.img into output directory... - | 1 file(s) moved. - | Generating Floppy Disk nzcom... - | cpmcp -f wbw_fd144 fd_nzcom.img d_nzcom/u0/*.* 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_fd144 fd_nzcom.img ../../Binary/Apps/Tunes/*.* 3: - | Adding System Image zsys_wbw... - | Moving image fd_nzcom.img into output directory... - | 1 file(s) moved. - | Generating Floppy Disk cpm3... - | cpmcp -f wbw_fd144 fd_cpm3.img d_cpm3/u0/*.* 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/cpmldr.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/ccp.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/gencpm.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/genres.dat 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/genbnk.dat 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/bios3.spr 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/bnkbios3.spr 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/bdos3.spr 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/bnkbdos3.spr 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/resbdos3.spr 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/cpm3res.sys 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/cpm3bnk.sys 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/gencpm.dat 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/cpm3.sys 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/readme.1st 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../CPM3/cpm3fix.pat 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_fd144 fd_cpm3.img ../../Binary/Apps/Tunes/*.* 3: - | Moving image fd_cpm3.img into output directory... - | 1 file(s) moved. - | Generating Floppy Disk zpm3... - | cpmcp -f wbw_fd144 fd_zpm3.img d_zpm3/u0/*.* 0: - | cpmcp -f wbw_fd144 fd_zpm3.img d_zpm3/u10/*.* 10: - | cpmcp -f wbw_fd144 fd_zpm3.img d_zpm3/u14/*.* 14: - | cpmcp -f wbw_fd144 fd_zpm3.img d_zpm3/u15/*.* 15: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/zpmldr.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/cpmldr.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/autotog.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/clrhist.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/setz3.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/cpm3.sys 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/zccp.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/zinstal.zpm 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/startzpm.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/makedos.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/gencpm.dat 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/bnkbios3.spr 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/bnkbdos3.spr 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../ZPM3/resbdos3.spr 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_fd144 fd_zpm3.img ../../Binary/Apps/Tunes/*.* 3: - | Moving image fd_zpm3.img into output directory... - | 1 file(s) moved. - | Generating Floppy Disk ws4... - | cpmcp -f wbw_fd144 fd_ws4.img d_ws4/u0/*.* 0: - | Moving image fd_ws4.img into output directory... - | 1 file(s) moved. - | : - | : Building Hard Disk Images... - | : - | Generating Hard Disk cpm22... - | cpmcp -f wbw_hd0 hd_cpm22.img d_cpm22/u0/*.* 0: - | cpmcp -f wbw_hd0 hd_cpm22.img d_cpm22/u1/*.* 1: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_hd0 hd_cpm22.img ../../Binary/Apps/Tunes/*.* 3: - | Adding System Image cpm_wbw... - | Moving image hd_cpm22.img into output directory... - | 1 file(s) moved. - | Generating Hard Disk zsdos... - | cpmcp -f wbw_hd0 hd_zsdos.img d_zsdos/u0/*.* 0: - | cpmcp -f wbw_hd0 hd_zsdos.img d_zsdos/u1/*.* 1: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_hd0 hd_zsdos.img ../../Binary/Apps/Tunes/*.* 3: - | Adding System Image zsys_wbw... - | Moving image hd_zsdos.img into output directory... - | 1 file(s) moved. - | Generating Hard Disk nzcom... - | cpmcp -f wbw_hd0 hd_nzcom.img d_nzcom/u0/*.* 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_hd0 hd_nzcom.img ../../Binary/Apps/Tunes/*.* 3: - | Adding System Image zsys_wbw... - | Moving image hd_nzcom.img into output directory... - | 1 file(s) moved. - | Generating Hard Disk cpm3... - | cpmcp -f wbw_hd0 hd_cpm3.img d_cpm3/u0/*.* 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/cpmldr.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/ccp.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/gencpm.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/genres.dat 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/genbnk.dat 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/bios3.spr 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/bnkbios3.spr 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/bdos3.spr 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/bnkbdos3.spr 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/resbdos3.spr 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/cpm3res.sys 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/cpm3bnk.sys 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/gencpm.dat 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/cpm3.sys 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/readme.1st 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../CPM3/cpm3fix.pat 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_hd0 hd_cpm3.img ../../Binary/Apps/Tunes/*.* 3: - | Moving image hd_cpm3.img into output directory... - | 1 file(s) moved. - | Generating Hard Disk zpm3... - | cpmcp -f wbw_hd0 hd_zpm3.img d_zpm3/u0/*.* 0: - | cpmcp -f wbw_hd0 hd_zpm3.img d_zpm3/u10/*.* 10: - | cpmcp -f wbw_hd0 hd_zpm3.img d_zpm3/u14/*.* 14: - | cpmcp -f wbw_hd0 hd_zpm3.img d_zpm3/u15/*.* 15: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/zpmldr.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/cpmldr.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/autotog.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/clrhist.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/setz3.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/cpm3.sys 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/zccp.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/zinstal.zpm 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/startzpm.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/makedos.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/gencpm.dat 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/bnkbios3.spr 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/bnkbdos3.spr 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../ZPM3/resbdos3.spr 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/assign.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/fat.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/fdu.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/format.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/mode.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/osldr.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/rtc.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/survey.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/syscopy.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/sysgen.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/talk.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/timer.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/xm.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/inttest.com 0: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/tune.com 3: - | cpmcp -f wbw_hd0 hd_zpm3.img ../../Binary/Apps/Tunes/*.* 3: - | Moving image hd_zpm3.img into output directory... - | 1 file(s) moved. - | Generating Hard Disk ws4... - | cpmcp -f wbw_hd0 hd_ws4.img d_ws4/u0/*.* 0: - | Moving image hd_ws4.img into output directory... - | 1 file(s) moved. diff --git a/Source/Images/d_cpm22/u0/KERCPM22.COM b/Source/Images/d_cpm22/u0/KERCPM22.COM new file mode 100644 index 00000000..e4d91f7c Binary files /dev/null and b/Source/Images/d_cpm22/u0/KERCPM22.COM differ diff --git a/Source/Images/d_cpm22/u0/MBASIC.COM b/Source/Images/d_cpm22/u0/MBASIC.COM deleted file mode 100644 index c9ec3cd3..00000000 Binary files a/Source/Images/d_cpm22/u0/MBASIC.COM and /dev/null differ diff --git a/Source/Images/d_cpm22/u0/SUBMIT.COM b/Source/Images/d_cpm22/u0/SUBMIT.COM index 2e788827..f651bfee 100644 Binary files a/Source/Images/d_cpm22/u0/SUBMIT.COM and b/Source/Images/d_cpm22/u0/SUBMIT.COM differ diff --git a/Source/Images/d_cpm3/u0/KERCPM3.COM b/Source/Images/d_cpm3/u0/KERCPM3.COM new file mode 100644 index 00000000..26d1b3fa Binary files /dev/null and b/Source/Images/d_cpm3/u0/KERCPM3.COM differ diff --git a/Source/Images/d_nzcom/u0/KERCPM22.COM b/Source/Images/d_nzcom/u0/KERCPM22.COM new file mode 100644 index 00000000..e4d91f7c Binary files /dev/null and b/Source/Images/d_nzcom/u0/KERCPM22.COM differ diff --git a/Source/Images/d_nzcom/u0/SUBMIT.COM b/Source/Images/d_nzcom/u0/SUBMIT.COM index 2e788827..f651bfee 100644 Binary files a/Source/Images/d_nzcom/u0/SUBMIT.COM and b/Source/Images/d_nzcom/u0/SUBMIT.COM differ diff --git a/Source/Images/d_zpm3/u15/kercpm3.com b/Source/Images/d_zpm3/u15/kercpm3.com new file mode 100644 index 00000000..26d1b3fa Binary files /dev/null and b/Source/Images/d_zpm3/u15/kercpm3.com differ diff --git a/Source/Images/d_zpm3/u15/mbasic.com b/Source/Images/d_zpm3/u15/mbasic.com deleted file mode 100644 index c9ec3cd3..00000000 Binary files a/Source/Images/d_zpm3/u15/mbasic.com and /dev/null differ diff --git a/Source/Images/d_zpm3/u15/tcview.com b/Source/Images/d_zpm3/u15/tcview.com new file mode 100644 index 00000000..9d12b757 Binary files /dev/null and b/Source/Images/d_zpm3/u15/tcview.com differ diff --git a/Source/Images/d_zpm3/u15/z3loc.com b/Source/Images/d_zpm3/u15/z3loc.com new file mode 100644 index 00000000..fab1359c Binary files /dev/null and b/Source/Images/d_zpm3/u15/z3loc.com differ diff --git a/Source/Images/d_zsdos/u0/KERCPM22.COM b/Source/Images/d_zsdos/u0/KERCPM22.COM new file mode 100644 index 00000000..e4d91f7c Binary files /dev/null and b/Source/Images/d_zsdos/u0/KERCPM22.COM differ diff --git a/Source/Images/d_zsdos/u0/MBASIC.COM b/Source/Images/d_zsdos/u0/MBASIC.COM deleted file mode 100644 index c9ec3cd3..00000000 Binary files a/Source/Images/d_zsdos/u0/MBASIC.COM and /dev/null differ diff --git a/Source/Images/diskdefs b/Source/Images/diskdefs index 937bfcf2..db9ef4b2 100644 --- a/Source/Images/diskdefs +++ b/Source/Images/diskdefs @@ -297,121 +297,169 @@ diskdef wbw_rom1024 os 2.2 end -# UNA 512KB ROM (128KB reserved, 384KB ROM Disk) +# RomWBW 720K floppy media +diskdef wbw_fd720 + seclen 512 + tracks 160 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom512 +# RomWBW 1.44M floppy media +diskdef wbw_fd144 seclen 512 - tracks 12 - sectrk 64 + tracks 160 + sectrk 18 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# UNA 512KB ROM (128KB reserved, 896KB ROM Disk) +# RomWBW 360K floppy media +diskdef wbw_fd360 + seclen 512 + tracks 80 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom1024 +# RomWBW 1.20M floppy media +diskdef wbw_fd120 seclen 512 - tracks 28 - sectrk 64 + tracks 160 + sectrk 15 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# RomWBW 8MB Hard Disk, LU 0-3 -diskdef wbw_hd0 +# RomWBW 8320KB Hard Disk Slice (512 directory entry format) +# Legacy format, 512 dir entries, 16,630 sectors / slice +diskdef wbw_hd512 seclen 512 - tracks 65 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 1 + boottrk 16 os 2.2 end -diskdef wbw_hd1 +# First 4 slices of wbw_hd512 +diskdef wbw_hd512_0 seclen 512 - tracks 130 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 66 + boottrk 16 os 2.2 end -diskdef wbw_hd2 +diskdef wbw_hd512_1 seclen 512 - tracks 195 - sectrk 256 + tracks 2080 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 131 + boottrk 1056 os 2.2 end -diskdef wbw_hd3 +diskdef wbw_hd512_2 seclen 512 - tracks 260 - sectrk 256 + tracks 3120 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 196 + boottrk 2096 os 2.2 end -# RomWBW 720K floppy media -diskdef wbw_fd720 +diskdef wbw_hd512_3 seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 4160 + sectrk 16 + blocksize 4096 + maxdir 512 skew 0 - boottrk 4 + boottrk 3136 os 2.2 end -# RomWBW 1.44M floppy media -diskdef wbw_fd144 + +# RomWBW 8MB Hard Disk (1024 directory entry format) +# New format, 1024 dir entries, 16,384 sectors / slice +# Pure filesystem image, no MBR prefix +diskdef wbw_hd1024 seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 + tracks 1024 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 boottrk 2 os 2.2 end -# RomWBW 360K floppy media -diskdef wbw_fd360 +# First 4 slices of wbw_hd1024 +# Assumes 128KB prefix (256 sectors) +diskdef wbw_hd1024_0 seclen 512 - tracks 80 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 1040 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 18 os 2.2 end -# RomWBW 1.20M floppy media -diskdef wbw_fd120 +diskdef wbw_hd1024_1 seclen 512 - tracks 160 - sectrk 15 - blocksize 2048 - maxdir 256 + tracks 2064 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 1042 + os 2.2 +end + +diskdef wbw_hd1024_2 + seclen 512 + tracks 3112 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 2066 + os 2.2 +end + +diskdef wbw_hd1024_3 + seclen 512 + tracks 4136 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 3114 os 2.2 end diff --git a/Source/Images/hd1024_prefix.dat b/Source/Images/hd1024_prefix.dat new file mode 100644 index 00000000..1ec28fa1 Binary files /dev/null and b/Source/Images/hd1024_prefix.dat differ diff --git a/Source/Makefile b/Source/Makefile index 166bb4c1..1184c624 100644 --- a/Source/Makefile +++ b/Source/Makefile @@ -2,14 +2,15 @@ # order is actually important, because of build dependencies # SUBDIRS = Prop -SUBDIRS += Apps +SUBDIRS += Apps SUBDIRS += CBIOS SUBDIRS += Forth SUBDIRS += Fonts SUBDIRS += CPM22 ZCPR ZCPR-DJ ZSDOS SUBDIRS += HBIOS CPM3 SUBDIRS += ZPM3 -SUBDIRS += BPBIOS +#SUBDIRS += BPBIOS SUBDIRS += Images +SUBDIRS += ZRC TOOLS = ../Tools include $(TOOLS)/Makefile.inc diff --git a/Source/Prop/Spin/ParPortProp.spin b/Source/Prop/Spin/ParPortProp.spin index 6ecf049f..5e890c21 100644 --- a/Source/Prop/Spin/ParPortProp.spin +++ b/Source/Prop/Spin/ParPortProp.spin @@ -3,8 +3,8 @@ ************************************ * ParPortProp for RomWBW * * Interface to RBC ParPortProp * - * Version 0.96 * - * March 11, 2018 * + * Version 0.97 * + * May 9, 2020 * ************************************ Wayne Warthen @@ -29,11 +29,12 @@ Updates: 2018-03-11 WBW: Implement character attributes + 2020-05-09 WBW: Switch monitor refresh to 60Hz }} CON - VERSION = (((0 << 8) + 96) << 16) + 0 + VERSION = (((0 << 8) + 97) << 16) + 0 _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 @@ -608,7 +609,7 @@ PRI Activity DAT -strVer byte "F/W v0.96",0 +strVer byte "F/W v0.97",0 strHW byte "ParPortProp",0 strROM byte "RomWBW",0 diff --git a/Source/Prop/Spin/PropIO.spin b/Source/Prop/Spin/PropIO.spin index 3d677264..9e074fe0 100644 --- a/Source/Prop/Spin/PropIO.spin +++ b/Source/Prop/Spin/PropIO.spin @@ -3,8 +3,8 @@ ******************************* * PropIO for RomWBW * * Interface to RBC PropIO * - * Version 0.96 * - * March 11, 2018 * + * Version 0.97 * + * May 9, 2020 * ******************************* Wayne Warthen @@ -34,11 +34,12 @@ 2014-02-09 WBW: Clean up 2015-11-15 WBW: Added SD card capacity reporting 2018-03-11 WBW: Implement character attributes + 2020-05-09 WBW: Switch monitor refresh to 60Hz }} CON - VERSION = (((0 << 8) + 96) << 16) + 0 + VERSION = (((0 << 8) + 97) << 16) + 0 _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 @@ -337,7 +338,7 @@ PRI DumpBuffer(Buffer) | i, j DAT -strVer byte "F/W v0.96",0 +strVer byte "F/W v0.97",0 strHW byte "PropIO",0 strROM byte "RomWBW",0 diff --git a/Source/Prop/Spin/PropIO2.spin b/Source/Prop/Spin/PropIO2.spin index 9e01d3cb..ad1592f7 100644 --- a/Source/Prop/Spin/PropIO2.spin +++ b/Source/Prop/Spin/PropIO2.spin @@ -3,8 +3,8 @@ ********************************* * PropIO 2 for RomWBW * * Interface to RBC PropIO 2 * - * Version 0.96 * - * March 11, 2018 * + * Version 0.97 * + * May 9, 2020 * ********************************* Wayne Warthen @@ -34,11 +34,12 @@ 2014-02-08 WBW: Adaptation for PropIO 2 2015-11-15 WBW: Added SD card capacity reporting 2018-03-11 WBW: Implement character attributes + 2020-05-09 WBW: Switch monitor refresh to 60Hz }} CON - VERSION = (((0 << 8) + 96) << 16) + 0 + VERSION = (((0 << 8) + 97) << 16) + 0 _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 @@ -337,7 +338,7 @@ PRI DumpBuffer(Buffer) | i, j DAT -strVer byte "F/W v0.96",0 +strVer byte "F/W v0.97",0 strHW byte "PropIO v2",0 strROM byte "RomWBW",0 diff --git a/Source/Prop/Spin/vgacolour.spin b/Source/Prop/Spin/vgacolour.spin index c5cc2f80..0981fe55 100644 --- a/Source/Prop/Spin/vgacolour.spin +++ b/Source/Prop/Spin/vgacolour.spin @@ -20,6 +20,7 @@ CON +{ ' 640 x 480 @ 69Hz settings: 80 x 30 characters hp = 640 ' horizontal pixels @@ -33,6 +34,24 @@ CON hn = 1 ' horizontal normal sync state (0|1) vn = 1 ' vertical normal sync state (0|1) pr = 30 ' pixel rate in MHz at 80MHz system clock (5MHz granularity) +} + +'{ +' 640 x 480 @ 60Hz settings: 80 x 40 characters + + hp = 640 'horizontal pixels + vp = 480 'vertical pixels + hf = 16 'horizontal front porch pixels + hs = 96 'horizontal sync pixels + hb = 48 'horizontal back porch pixels + vf = 10 'vertical front porch lines + vs = 2 'vertical sync lines + vb = 33 'vertical back porch lines + hn = 1 'horizontal normal sync state (0|1) + vn = 1 'vertical normal sync state (0|1) + pr = 25 'pixel rate in MHz at 80MHz system clock (5MHz granularity) +'} + ' columns and rows diff --git a/Source/RomDsk/ROM_1024KB/CLRDIR.COM b/Source/RomDsk/ROM_1024KB/CLRDIR.COM index c6b05cc9..ca65cbed 100644 Binary files a/Source/RomDsk/ROM_1024KB/CLRDIR.COM and b/Source/RomDsk/ROM_1024KB/CLRDIR.COM differ diff --git a/Source/RomDsk/ROM_1024KB/FDISK80.COM b/Source/RomDsk/ROM_1024KB/FDISK80.COM index 0d73cef2..7e862d67 100644 Binary files a/Source/RomDsk/ROM_1024KB/FDISK80.COM and b/Source/RomDsk/ROM_1024KB/FDISK80.COM differ diff --git a/Source/RomDsk/ROM_1024KB/FLASH.COM b/Source/RomDsk/ROM_1024KB/FLASH.COM index 1b7fa64c..c81f9c54 100644 Binary files a/Source/RomDsk/ROM_1024KB/FLASH.COM and b/Source/RomDsk/ROM_1024KB/FLASH.COM differ diff --git a/Source/RomDsk/ROM_512KB/CLRDIR.COM b/Source/RomDsk/ROM_512KB/CLRDIR.COM index c6b05cc9..ca65cbed 100644 Binary files a/Source/RomDsk/ROM_512KB/CLRDIR.COM and b/Source/RomDsk/ROM_512KB/CLRDIR.COM differ diff --git a/Source/RomDsk/ROM_512KB/FDISK80.COM b/Source/RomDsk/ROM_512KB/FDISK80.COM index 0d73cef2..7e862d67 100644 Binary files a/Source/RomDsk/ROM_512KB/FDISK80.COM and b/Source/RomDsk/ROM_512KB/FDISK80.COM differ diff --git a/Source/RomDsk/ROM_512KB/FLASH.COM b/Source/RomDsk/ROM_512KB/FLASH.COM index 1b7fa64c..c81f9c54 100644 Binary files a/Source/RomDsk/ROM_512KB/FLASH.COM and b/Source/RomDsk/ROM_512KB/FLASH.COM differ diff --git a/Source/UBIOS/ubios.inc b/Source/UBIOS/ubios.inc index 546c671d..58684c02 100644 --- a/Source/UBIOS/ubios.inc +++ b/Source/UBIOS/ubios.inc @@ -11,27 +11,17 @@ BF_CIOOST .EQU BF_CIO + 4 ; CHARACTER OUTPUT STATUS BF_DIO .EQU $40 BF_DIOREAD .EQU BF_DIO + 2 ; DISK READ BF_DIOWRITE .EQU BF_DIO + 3 ; DISK WRITE -;; -;; MEMORY BANK CONFIGURATION -;; -;ROMSIZE .EQU 512 -;RAMSIZE .EQU 512 ; -;BID_ROM0 .EQU $0000 -;BID_ROMN .EQU (BID_ROM0 + ((ROMSIZE / 32) - 1)) -;BID_RAM0 .EQU $8000 -;BID_RAMN .EQU (BID_RAM0 + ((RAMSIZE / 32) - 1)) +; MEDIA ID VALUES ; -;BID_BOOT .EQU BID_ROM0 ; BOOT BANK -;BID_BIOSIMG .EQU BID_ROM0 + 1 ; BIOS IMAGE BANK -;BID_OSIMG .EQU BID_ROM0 + 2 ; ROM LOADER AND IMAGES BANK -;BID_FSFAT .EQU BID_ROM0 + 3 ; FAT FILESYSTEM DRIVER BANK -;BID_ROMD0 .EQU BID_ROM0 + 4 ; FIRST ROM DRIVE BANK -;BID_ROMDN .EQU BID_ROMN ; LAST ROM DRIVE BANK -; -;BID_RAMD0 .EQU BID_RAM0 ; FIRST RAM DRIVE BANK -;BID_RAMDN .EQU BID_RAMN - 4 ; LAST RAM DRIVE BANK -;BID_AUX .EQU BID_RAMN - 3 ; AUX BANK (BPBIOS, ETC.) -;BID_BIOS .EQU BID_RAMN - 2 ; BIOS BANK -;BID_USR .EQU BID_RAMN - 1 ; USER BANK (CP/M TPA, ETC.) -;BID_COM .EQU BID_RAMN ; COMMON BANK, UPPER 32K +MID_NONE .EQU 0 +MID_MDROM .EQU 1 +MID_MDRAM .EQU 2 +MID_RF .EQU 3 +MID_HD .EQU 4 +MID_FD720 .EQU 5 +MID_FD144 .EQU 6 +MID_FD360 .EQU 7 +MID_FD120 .EQU 8 +MID_FD111 .EQU 9 +MID_HDNEW .EQU 10 diff --git a/Source/ZPM3/Build.cmd b/Source/ZPM3/Build.cmd index 47018c83..5430167b 100644 --- a/Source/ZPM3/Build.cmd +++ b/Source/ZPM3/Build.cmd @@ -17,18 +17,20 @@ copy ..\ZCCP\startzpm.com . copy ..\CPM3\genbnk.dat . copy ..\CPM3\zpmbios3.spr bnkbios3.spr copy ..\CPM3\gencpm.com . +copy ..\CPM3\util.rel . copy ..\CPM3\biosldrd.rel . copy ..\CPM3\biosldrc.rel . -rem copy ..\CPM3\cpmldr.com . +copy ..\CPM3\cpmldr.com . +copy ..\CPM3\cpmldr.sys . rem ZPM Loader echo. echo. echo *** ZPM Loader *** echo. -zx LINK -ZPMLDRD[L100]=ZPM3LDR,BIOSLDRD +zx LINK -ZPMLDRD[L100]=ZPM3LDR,BIOSLDRD,UTIL move /Y zpmldrd.com zpmldr.bin -zx LINK -ZPMLDRC[L100]=ZPM3LDR,BIOSLDRC +zx LINK -ZPMLDRC[L100]=ZPM3LDR,BIOSLDRC,UTIL move /Y zpmldrc.com zpmldr.com rem pause @@ -41,8 +43,32 @@ copy genbnk.dat gencpm.dat zx gencpm -auto -display rem pause +rem ZPM3 Tools +zx Z80ASM -clrhist/F +zx Z80ASM -setz3/F +zx Z80ASM -autotog/F + rem Loader tasm -t80 -g3 -fFF loader.asm loader.bin loader.lst copy /b loader.bin + zpmldr.bin zpmldr.sys + +rem Copy OS files to Binary directory + +copy zpmldr.com ..\..\Binary\ZPM3 +copy zpmldr.sys ..\..\Binary\ZPM3 +copy cpmldr.com ..\..\Binary\ZPM3 +copy cpmldr.sys ..\..\Binary\ZPM3 +copy autotog.com ..\..\Binary\ZPM3 +copy clrhist.com ..\..\Binary\ZPM3 +copy setz3.com ..\..\Binary\ZPM3 +copy cpm3.sys ..\..\Binary\ZPM3 +copy zccp.com ..\..\Binary\ZPM3 +copy zinstal.zpm ..\..\Binary\ZPM3 +copy startzpm.com ..\..\Binary\ZPM3 +copy makedos.com ..\..\Binary\ZPM3 +copy gencpm.dat ..\..\Binary\ZPM3 +copy bnkbios3.spr ..\..\Binary\ZPM3 +copy bnkbdos3.spr ..\..\Binary\ZPM3 +copy resbdos3.spr ..\..\Binary\ZPM3 diff --git a/Source/ZPM3/Clean.cmd b/Source/ZPM3/Clean.cmd index 57295d69..3c953899 100644 --- a/Source/ZPM3/Clean.cmd +++ b/Source/ZPM3/Clean.cmd @@ -10,11 +10,15 @@ if exist system.epr del system.epr if exist system.evn del system.evn if exist system.odd del system.odd if exist biosldr.rel del biosldr.rel +if exist util.rel del util.rel if exist *.sym del *.sym if exist zpmldr.com del zpmldr.com if exist cpmldr.com del cpmldr.com if exist startzpm.com del startzpm.com if exist gencpm.com del gencpm.com +if exist clrhist.com del clrhist.com +if exist setz3.com del setz3.com +if exist autotog.com del autotog.com if exist *.dat del *.dat if exist biosldr?.rel del biosldr?.rel if exist *.bin del *.bin diff --git a/Source/ZPM3/Makefile b/Source/ZPM3/Makefile index d72e77bd..46d98359 100644 --- a/Source/ZPM3/Makefile +++ b/Source/ZPM3/Makefile @@ -1,20 +1,19 @@ OBJECTS = zpmldr.com zpmldr.sys cpm3.sys startzpm.com zccp.com -ifdef REBUILD_ZPM_TOOLS +NODELETE = makedos.com zinstal.zpm bnkbdos3.spr resbdos3.spr OBJECTS += setz3.com clrhist.com autotog.com -else -NODELETE = setz3.com clrhist.com autotog.com -endif -OTHERS = zpmldr.bin loader.bin biosldrd.rel biosldrc.rel gencpm.com gencpm.dat bnkbios3.spr +OBJECTS += cpmldr.com cpmldr.sys zinstal.zpm makedos.com gencpm.dat bnkbios3.spr bnkbdos3.spr resbdos3.spr +OTHERS = zpmldr.bin loader.bin biosldrd.rel biosldrc.rel util.rel gencpm.com +DEST = ../../Binary/ZPM3/ TOOLS =../../Tools include $(TOOLS)/Makefile.inc -zpmldr.bin: zpm3ldr.rel biosldrd.rel - $(ZXCC) $(CPM)/LINK -ZPMLDRD[L100]=ZPM3LDR,BIOSLDRD +zpmldr.bin: zpm3ldr.rel biosldrd.rel util.rel + $(ZXCC) $(CPM)/LINK -ZPMLDRD[L100]=ZPM3LDR,BIOSLDRD,UTIL mv zpmldrd.com zpmldr.bin -zpmldr.com: zpm3ldr.rel biosldrc.rel - $(ZXCC) $(CPM)/LINK -ZPMLDRC[L100]=ZPM3LDR,BIOSLDRC +zpmldr.com: zpm3ldr.rel biosldrc.rel util.rel + $(ZXCC) $(CPM)/LINK -ZPMLDRC[L100]=ZPM3LDR,BIOSLDRC,UTIL mv zpmldrc.com zpmldr.com zpmldr.sys: zpmldr.bin loader.bin @@ -38,6 +37,9 @@ biosldrc.rel: ../CPM3/biosldrc.rel biosldrd.rel: ../CPM3/biosldrd.rel cp $< $@ +util.rel: ../CPM3/util.rel + cp $< $@ + zccp.com: ../ZCCP/ccp.com cp $< $@ @@ -47,8 +49,8 @@ zinstal.zpm: ../ZCCP/zinstal.zpm startzpm.com: ../ZCCP/startzpm.com cp $< $@ -setz3.com: setz3.z80 - -clrhist.com: clrhist.z80 +cpmldr.com: ../CPM3/cpmldr.com + cp $< $@ -autotog.com: autotog.z80 +cpmldr.sys: ../CPM3/cpmldr.sys + cp $< $@ diff --git a/Source/ZPM3/autotog.com b/Source/ZPM3/autotog.com deleted file mode 100644 index 3c7a5980..00000000 Binary files a/Source/ZPM3/autotog.com and /dev/null differ diff --git a/Source/ZPM3/autotog.z80 b/Source/ZPM3/autotog.z80 index b59a6663..9862af58 100644 --- a/Source/ZPM3/autotog.z80 +++ b/Source/ZPM3/autotog.z80 @@ -45,13 +45,13 @@ ACPoff equ 85h ; Offset in SCB base page of Auto Command Prompting bit HELPmsg: db ' SYNTAX:' db 10,13 - db ' AUTOTOG Toggles the state of the Auto Command Prompting' + db ' AUTOTOG Toggles the state of the Auto Command Prompting' db 10,13 - db ' AUTOTOG ON Enables Auto Command Prompting' + db ' AUTOTOG ON Enables Auto Command Prompting' db 10,13 - db ' AUTOTOG OFF Disables Auto Command Prompting' + db ' AUTOTOG OFF Disables Auto Command Prompting' db 10,13 - db ' AUTOTOG // Displays a brief help message' + db ' AUTOTOG // Displays a brief help message' db '$' ONmsg: db 'ZPM3 Auto Command Prompting is now enabled. Toggle with ^Q.' diff --git a/Source/ZPM3/clrhist.com b/Source/ZPM3/clrhist.com deleted file mode 100644 index 02a39c83..00000000 Binary files a/Source/ZPM3/clrhist.com and /dev/null differ diff --git a/Source/ZPM3/loader.asm b/Source/ZPM3/loader.asm index ef80711d..cc2ffc0a 100644 --- a/Source/ZPM3/loader.asm +++ b/Source/ZPM3/loader.asm @@ -27,9 +27,13 @@ ; #INCLUDE "../ver.inc" ; +; BELOW, SYS_END MUST BE SET TO THE SIZE OF CPMLDR.BIN + SYS_LOC. IF +; THE SIZE OF ZPMLDR.BIN CHANGES, SYS_SIZ MUST BE UPDATED!!! +; +SYS_SIZ .EQU $0F00 ; SIZE OF CPMLDR.BIN SYS_ENT .EQU $0100 ; SYSTEM (OS) ENTRY POINT ADDRESS SYS_LOC .EQU $0100 ; STARTING ADDRESS TO LOAD SYSTEM IMAGE -SYS_END .EQU $1480 ; ENDING ADDRESS OF SYSTEM IMAGE +SYS_END .EQU SYS_SIZ + SYS_LOC ; ENDING ADDRESS OF SYSTEM IMAGE ; SEC_SIZE .EQU 512 ; DISK SECTOR SIZE BLK_SIZE .EQU 128 ; OS BLOCK/RECORD SIZE diff --git a/Source/ZPM3/setz3.com b/Source/ZPM3/setz3.com deleted file mode 100644 index 4ddb374f..00000000 Binary files a/Source/ZPM3/setz3.com and /dev/null differ diff --git a/Source/ZRC/Build.cmd b/Source/ZRC/Build.cmd new file mode 100644 index 00000000..e4be1f07 --- /dev/null +++ b/Source/ZRC/Build.cmd @@ -0,0 +1,13 @@ +@echo off +setlocal + +if not exist ..\..\Binary\RCZ80_zrc.rom goto :err + +copy /b zrc_cfldr.bin + zrc_ptbl.bin + zrc_fill_1.bin + zrc_mon.bin + zrc_fill_2.bin + ..\..\Binary\RCZ80_zrc.rom + zrc_fill_3.bin ..\..\Binary\hd1024_zrc_prefix.dat + +goto :eof + +:err + +echo *** Can't build ZRC prefix file -- missing "..\..\Binary\RCZ80_zrc.rom" +exit /b 1 \ No newline at end of file diff --git a/Source/ZRC/Clean.cmd b/Source/ZRC/Clean.cmd new file mode 100644 index 00000000..fa12c5c7 --- /dev/null +++ b/Source/ZRC/Clean.cmd @@ -0,0 +1,3 @@ +@echo off +setlocal + diff --git a/Source/ZRC/Makefile b/Source/ZRC/Makefile new file mode 100644 index 00000000..aed2c80b --- /dev/null +++ b/Source/ZRC/Makefile @@ -0,0 +1,19 @@ +HD1024ZRCPREFIX = hd1024_zrc_prefix.dat +ZRCROM = ../../Binary/RCZ80_zrc.rom + +OBJECTS := + +ifneq ($(wildcard $(ZRCROM)),) + OBJECTS += $(HD1024ZRCPREFIX) +endif + +DEST=../../Binary + +TOOLS = ../../Tools + +include $(TOOLS)/Makefile.inc + +DIFFPATH = $(DIFFTO)/Binary + +$(HD1024ZRCPREFIX): + cat zrc_cfldr.bin zrc_ptbl.bin zrc_fill_1.bin zrc_mon.bin zrc_fill_2.bin $(ZRCROM) zrc_fill_3.bin >$@ \ No newline at end of file diff --git a/Source/ZRC/ZRC Disk Layout.txt b/Source/ZRC/ZRC Disk Layout.txt new file mode 100644 index 00000000..7f8e3975 --- /dev/null +++ b/Source/ZRC/ZRC Disk Layout.txt @@ -0,0 +1,16 @@ +CF Boot Loader: Sector 0 (bytes 0-255) +RomWBW Partition Table: Sector 0 (bytes 256-511) +ZRC Monitor: Sectors 0xF8-0xFF (bytes 0x1F000-0x1FFFF) +RomWBW: Sectors 0x120-0x51F (bytes 0x24000-0xA3FFF) +Start of Slices (0x1E partition): Sector 0x800 (byte 0x100000) + +Start Length Description +------- ------- --------------------------- +0x00000 0x00100 CF Boot Loader +0x00100 0x00100 RomWBW Partition Table +0x00200 0x1EE00 Filler +0x1F000 0x01000 ZRC Monitor +0x20000 0x04000 Filler +0x24000 0x80000 RomWBW +0xA4000 0x5C000 Filler +0x100000: Start of slices (partition 0x1E) \ No newline at end of file diff --git a/Source/ZRC/zrc_cfldr.bin b/Source/ZRC/zrc_cfldr.bin new file mode 100644 index 00000000..9a28f43b Binary files /dev/null and b/Source/ZRC/zrc_cfldr.bin differ diff --git a/Source/ZRC/zrc_fill_1.bin b/Source/ZRC/zrc_fill_1.bin new file mode 100644 index 00000000..705bedcd Binary files /dev/null and b/Source/ZRC/zrc_fill_1.bin differ diff --git a/Source/ZRC/zrc_fill_2.bin b/Source/ZRC/zrc_fill_2.bin new file mode 100644 index 00000000..294f4016 Binary files /dev/null and b/Source/ZRC/zrc_fill_2.bin differ diff --git a/Source/ZRC/zrc_fill_3.bin b/Source/ZRC/zrc_fill_3.bin new file mode 100644 index 00000000..a461d083 Binary files /dev/null and b/Source/ZRC/zrc_fill_3.bin differ diff --git a/Source/ZRC/zrc_mon.bin b/Source/ZRC/zrc_mon.bin new file mode 100644 index 00000000..ae6c886c Binary files /dev/null and b/Source/ZRC/zrc_mon.bin differ diff --git a/Source/ZRC/zrc_ptbl.bin b/Source/ZRC/zrc_ptbl.bin new file mode 100644 index 00000000..ca19be4c Binary files /dev/null and b/Source/ZRC/zrc_ptbl.bin differ diff --git a/Source/ver.inc b/Source/ver.inc index 91ca16d7..8f61eb17 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -1,5 +1,5 @@ #DEFINE RMJ 3 #DEFINE RMN 1 -#DEFINE RUP 0 +#DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1-pre.2" +#DEFINE BIOSVER "3.1.1-pre.42" diff --git a/Source/ver.lib b/Source/ver.lib index bc39cfbf..79b09e58 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -1,7 +1,7 @@ rmj equ 3 rmn equ 1 -rup equ 0 +rup equ 1 rtp equ 0 biosver macro - db "3.1-pre.2" + db "3.1.1-pre.42" endm diff --git a/Tools/Makefile.inc b/Tools/Makefile.inc index 4d0c5583..46d8dc48 100644 --- a/Tools/Makefile.inc +++ b/Tools/Makefile.inc @@ -24,7 +24,7 @@ RELPATH := $(subst $(TREEROOT),,$(HERE)) # # where's a copy of this tree for windows so we can diff binaries # -WINROOT = $(TREEROOT)/../RomWBW.windows +WINROOT = $(TREEROOT)/../RomWBW.windows DIFFTO := $(shell if [ -d $(WINROOT) ] ; then cd $(WINROOT); pwd; fi) DIFFPATH := $(DIFFTO)/$(RELPATH) @@ -57,7 +57,7 @@ CPM=$(TOOLS)/cpm/bin %.hex: %.asm $(ZXCC) $(CPM)/MAC -$< -$$PO ; \ - + %.bin: %.ASM $(ZXCC) $(CPM)/MAC -$< -$$PO $(ZXCC) $(CPM)/MLOAD25 -tmp.bin=$*.hex @@ -66,8 +66,9 @@ CPM=$(TOOLS)/cpm/bin %.com: %.z80 $(ZXCC) $(CPM)/Z80ASM -$(basename $<)/F ; \ + rm -f /tmp/casefn.cache ; \ mv $$($(CASEFN) $@) tmp.com ; mv tmp.com $@ - + %.bin: %.asm $(TASM) $< $@ @@ -77,11 +78,11 @@ CPM=$(TOOLS)/cpm/bin %.rel: %.z80 $(ZXCC) $(CPM)/Z80ASM -$(basename $<)/MF -%.hex: %.180 +%.hex: %.180 $(ZXCC) $(CPM)/SLR180 -$(basename $<)/HF -%.rel: %.azm - $(ZXCC) $(CPM)/ZSM =$< +%.rel: %.azm + $(ZXCC) $(CPM)/ZSM =$< -/L %.bin: %.rel $(ZXCC) $(CPM)/LINK -$@=$< @@ -94,6 +95,8 @@ ifeq ($(UNAME), Linux) $(BSTC) -e -l $< endif +.ONESHELL: + # # darwin bstc won't run, since mac os does not do 32 bit binaries any more # openspin ought to work @@ -108,11 +111,12 @@ endif # all:: $(OBJECTS) @for dir in $(SUBDIRS) ; do \ - ( echo "building in `pwd`/$$dir" ; cd "$$dir" ; make all ) ; \ + ( echo "building in `pwd`/$$dir" ; $(MAKE) --directory "$$dir" all ) ; \ done - @if [ "$(DEST)" ] ; then for file in $(OBJECTS) ; do \ + @if [ "$(DEST)" ] ; then for file in $(filter-out $(NOCOPY),$(OBJECTS)) ; do \ mkdir -p $(DEST) ; \ echo copy $$file to $(DEST) ; \ + rm -f /tmp/casefn.cache ; \ cp $$($(CASEFN) $$file) $(DEST) ; \ done ; fi @if [ "$(DOCDEST)" ] ; then for file in $(DOCS) ; do \ @@ -141,7 +145,7 @@ clobber:: clean # the same objects # diff:: -ifneq ($(DIFFTO),) +ifneq ($(DIFFTO),) @for dir in $(SUBDIRS) ; do \ ( echo "diff in $(HERE)/$$dir" ; cd "$$dir" ; make diff ) ; \ done @@ -164,8 +168,8 @@ ifneq ($(DIFFTO),) if [ ! -f "$$df" ] ; then echo $(DIFFPATH)/$$i missing ; fi ; \ fi ; \ done -endif - -vdiff: - make VERBOSEDIFF=2 diff +endif + +vdiff: + make VERBOSEDIFF=2 diff diff --git a/Tools/cpm/bin/ZSM.COM b/Tools/cpm/bin/ZSM.COM index 3704c8d9..e7504177 100644 Binary files a/Tools/cpm/bin/ZSM.COM and b/Tools/cpm/bin/ZSM.COM differ diff --git a/Tools/cpmtools/diskdefs b/Tools/cpmtools/diskdefs index 937bfcf2..db9ef4b2 100644 --- a/Tools/cpmtools/diskdefs +++ b/Tools/cpmtools/diskdefs @@ -297,121 +297,169 @@ diskdef wbw_rom1024 os 2.2 end -# UNA 512KB ROM (128KB reserved, 384KB ROM Disk) +# RomWBW 720K floppy media +diskdef wbw_fd720 + seclen 512 + tracks 160 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom512 +# RomWBW 1.44M floppy media +diskdef wbw_fd144 seclen 512 - tracks 12 - sectrk 64 + tracks 160 + sectrk 18 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# UNA 512KB ROM (128KB reserved, 896KB ROM Disk) +# RomWBW 360K floppy media +diskdef wbw_fd360 + seclen 512 + tracks 80 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom1024 +# RomWBW 1.20M floppy media +diskdef wbw_fd120 seclen 512 - tracks 28 - sectrk 64 + tracks 160 + sectrk 15 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# RomWBW 8MB Hard Disk, LU 0-3 -diskdef wbw_hd0 +# RomWBW 8320KB Hard Disk Slice (512 directory entry format) +# Legacy format, 512 dir entries, 16,630 sectors / slice +diskdef wbw_hd512 seclen 512 - tracks 65 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 1 + boottrk 16 os 2.2 end -diskdef wbw_hd1 +# First 4 slices of wbw_hd512 +diskdef wbw_hd512_0 seclen 512 - tracks 130 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 66 + boottrk 16 os 2.2 end -diskdef wbw_hd2 +diskdef wbw_hd512_1 seclen 512 - tracks 195 - sectrk 256 + tracks 2080 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 131 + boottrk 1056 os 2.2 end -diskdef wbw_hd3 +diskdef wbw_hd512_2 seclen 512 - tracks 260 - sectrk 256 + tracks 3120 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 196 + boottrk 2096 os 2.2 end -# RomWBW 720K floppy media -diskdef wbw_fd720 +diskdef wbw_hd512_3 seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 4160 + sectrk 16 + blocksize 4096 + maxdir 512 skew 0 - boottrk 4 + boottrk 3136 os 2.2 end -# RomWBW 1.44M floppy media -diskdef wbw_fd144 + +# RomWBW 8MB Hard Disk (1024 directory entry format) +# New format, 1024 dir entries, 16,384 sectors / slice +# Pure filesystem image, no MBR prefix +diskdef wbw_hd1024 seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 + tracks 1024 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 boottrk 2 os 2.2 end -# RomWBW 360K floppy media -diskdef wbw_fd360 +# First 4 slices of wbw_hd1024 +# Assumes 128KB prefix (256 sectors) +diskdef wbw_hd1024_0 seclen 512 - tracks 80 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 1040 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 18 os 2.2 end -# RomWBW 1.20M floppy media -diskdef wbw_fd120 +diskdef wbw_hd1024_1 seclen 512 - tracks 160 - sectrk 15 - blocksize 2048 - maxdir 256 + tracks 2064 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 1042 + os 2.2 +end + +diskdef wbw_hd1024_2 + seclen 512 + tracks 3112 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 2066 + os 2.2 +end + +diskdef wbw_hd1024_3 + seclen 512 + tracks 4136 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 3114 os 2.2 end diff --git a/Tools/lzsa/lzsa.exe b/Tools/lzsa/lzsa.exe index 1c1927d7..f7ad5895 100644 Binary files a/Tools/lzsa/lzsa.exe and b/Tools/lzsa/lzsa.exe differ diff --git a/Tools/simh/Sim.cfg b/Tools/simh/Sim.cfg index 8c8af2bf..dc1e25ab 100644 --- a/Tools/simh/Sim.cfg +++ b/Tools/simh/Sim.cfg @@ -23,12 +23,12 @@ attach n8vem0 %1 ; hard disks ;set hdsk debug=read;write;verbose -attach hdsk0 ..\..\Binary\hd_combo.img -attach hdsk1 ..\..\Binary\hd_combo.img +attach hdsk0 ..\..\Binary\hd512_combo.img +attach hdsk1 ..\..\Binary\hd1024_combo.img set hdsk0 format=HDSK set hdsk1 format=HDSK -set hdsk0 geom=T:2048/N:256/S:512 -set hdsk1 geom=T:2048/N:256/S:512 +set hdsk0 geom=T:8192/N:256/S:512 +set hdsk1 geom=T:8192/N:256/S:512 set hdsk0 wrtenb set hdsk1 wrtenb diff --git a/Tools/unix/lzsa/BlockFormat_LZSA2.md b/Tools/unix/lzsa/BlockFormat_LZSA2.md index 15ec3781..2a9b6c3f 100644 --- a/Tools/unix/lzsa/BlockFormat_LZSA2.md +++ b/Tools/unix/lzsa/BlockFormat_LZSA2.md @@ -44,7 +44,7 @@ The match offset is decoded according to the XYZ bits in the token XYZ 00Z 5-bit offset: read a nibble for offset bits 1-4 and use the inverted bit Z of the token as bit 0 of the offset. set bits 5-15 of the offset to 1. 01Z 9-bit offset: read a byte for offset bits 0-7 and use the inverted bit Z for bit 8 of the offset. set bits 9-15 of the offset to 1. - 10Z 13-bit offset: read a nibble for offset bits 9-12 and use the inverted bit Z for bit 8 of the offset, then read a byte for offset bits 0-7. set bits 13-15 of the offset to 1. + 10Z 13-bit offset: read a nibble for offset bits 9-12 and use the inverted bit Z for bit 8 of the offset, then read a byte for offset bits 0-7. set bits 13-15 of the offset to 1. substract 512 from the offset to get the final value. 110 16-bit offset: read a byte for offset bits 8-15, then another byte for offset bits 0-7. 111 repeat offset: reuse the offset value of the previous match command. diff --git a/Tools/unix/lzsa/README.md b/Tools/unix/lzsa/README.md index 6430ee5c..4646c8fb 100644 --- a/Tools/unix/lzsa/README.md +++ b/Tools/unix/lzsa/README.md @@ -7,6 +7,16 @@ Check out [The Hollow](https://www.pouet.net/prod.php?which=81909) by Darklite a [Gabba](https://www.pouet.net/prod.php?which=83539) by Stardust ranked 2nd in the ZX Spectrum demo compo at CAFe demoparty 2019 and also used LZSA on Z80. +[Myst Demake](http://www.deater.net/weave/vmwprod/mist/) for the Apple II by Vince Weaver, uses LZSA on 6502. + +The 8 bit guy's [Commander X16 ROM](https://github.com/commanderx16/x16-rom) uses LZSA on 6502 as well. + +[RomWBW](https://github.com/wwarthen/RomWBW) uses LZSA on Z80 for a variety of hobbyist computers. + +The popular [rasm](https://github.com/EdouardBERGE/rasm) assembler for Z80 features LZSA-compressed data sections. + +The [desolate](https://github.com/nzeemin/spectrum-desolate) game port to the ZX Spectrum uses LZSA compression on Z80. + The LZSA compression tool uses an aggressive optimal packing strategy to try to find the sequence of commands that gives the smallest packed file that decompresses to the original while maintaining the maximum possible decompression speed. The compression formats give the user choices that range from decompressing faster than LZ4 on 8-bit systems with better compression, to compressing as well as ZX7 with much better decompression speed. LZSA1 is designed to replace LZ4 and LZSA2 to replace ZX7, in 8-bit scenarios. @@ -55,7 +65,7 @@ Inspirations: * [LZ5/Lizard](https://github.com/inikep/lizard) by Przemyslaw Skibinski and Yann Collet. * The suffix array intervals in [Wimlib](https://wimlib.net/git/?p=wimlib;a=tree) by Eric Biggers. * ZX7 by Einar Saukas -* [apc](https://github.com/svendahl/cap) by Sven-ke Dahl +* [apc](https://github.com/svendahl/cap) by Sven-Åke Dahl * [Charles Bloom](http://cbloomrants.blogspot.com/)'s compression blog License: @@ -65,14 +75,19 @@ License: 8-bit assembly code: -* Z80 decompressors (size- and speed-optimized) written by [introspec](https://github.com/specke) +* Z80 decompressors (size- and speed-optimized) written by [introspec](https://github.com/specke) with optimizations by [uniabis](https://github.com/uniabis) * 6502 and 8088 size-optimized improvements by [Peter Ferrie](https://github.com/peterferrie) +* 6502 speed-optimized decompressor by [John Brandwood](https://github.com/jbrandwood) * 8088 speed-optimized decompressor by [Jim Leonard](https://github.com/mobygamer) +* 6809 decompressors (Tandy CoCo, Thomson MO/TO, Dragon 32/64..) optimized by [Doug Masten](https://github.com/dougmasten) +* Hitachi 6309 decompressors (Tandy CoCo 3) also contributed by [Doug Masten](https://github.com/dougmasten) External links: * [i8080 decompressors](https://gitlab.com/ivagor/lzsa8080/tree/master) by Ivan Gorodetsky * [PDP-11 decompressors](https://gitlab.com/ivagor/lzsa8080/tree/master/PDP11) also by Ivan Gorodetsky +* [MC68000 decompressors](https://github.com/tattlemuss/lz4-m68k/blob/master/src/lzsa.s) by Steven Tattersall +* [Gameboy decompressors](https://github.com/meltycode) by Meltycode, based on the Z80 code by introspec * LZSA's page on [Pouet](https://www.pouet.net/prod.php?which=81573) # Compressed format diff --git a/Tools/unix/lzsa/StreamFormat.md b/Tools/unix/lzsa/StreamFormat.md index 3f37f868..8eebb7e3 100644 --- a/Tools/unix/lzsa/StreamFormat.md +++ b/Tools/unix/lzsa/StreamFormat.md @@ -17,7 +17,7 @@ The 3-bytes LZSA header contains a signature and a traits byte: Trait bits: -* V: 3 bit code that indicates which block data encoding is used. 0 is LZSA1 and 2 is LZSA2. +* V: 3 bit code that indicates which block data encoding is used. 0 is LZSA1 and 1 is LZSA2. * Z: these bits in the traits are set to 0 for LZSA1 and LZSA2. # Frame format diff --git a/Tools/unix/lzsa/asm/6502/decompress_fast_v1.asm b/Tools/unix/lzsa/asm/6502/decompress_fast_v1.asm index b36cc176..7aa651d4 100644 --- a/Tools/unix/lzsa/asm/6502/decompress_fast_v1.asm +++ b/Tools/unix/lzsa/asm/6502/decompress_fast_v1.asm @@ -68,7 +68,7 @@ LARGE_VARLEN_LITERALS ; handle 16 bits literals count JSR GETLARGESRC ; grab low 8 bits in X, high 8 bits in A TAY ; put high 8 bits in Y TXA - JMP PREPARE_COPY_LARGE_LITERALS + BCS PREPARE_COPY_LARGE_LITERALS ; (*like JMP PREPARE_COPY_LITERALS_DIRECT but shorter) PREPARE_COPY_LITERALS TAX diff --git a/Tools/unix/lzsa/asm/6502/decompress_fast_v2.asm b/Tools/unix/lzsa/asm/6502/decompress_fast_v2.asm index 681d42d9..1e49a75d 100644 --- a/Tools/unix/lzsa/asm/6502/decompress_fast_v2.asm +++ b/Tools/unix/lzsa/asm/6502/decompress_fast_v2.asm @@ -114,11 +114,9 @@ NO_LITERALS BNE GOT_OFFSET_LO ; go store low byte of match offset and prepare match OFFSET_9_BIT ; 01Z: 9 bit offset - ;;ASL ; shift Z (offset bit 8) in place - ROL - ROL - AND #$01 - EOR #$FF ; set offset bits 15-9 to 1 + ROL ; carry: Z bit; A: xxxxxxx1 (carry known set from BCS OFFSET_9_BIT) + ADC #$00 ; if Z bit is set, add 1 to A (bit 0 of A is now 0), otherwise bit 0 is 1 + ORA #$FE ; set offset bits 15-9 to 1. reversed Z is already in bit 0 BNE GOT_OFFSET_HI ; go store high byte, read low byte of match offset and prepare match ; (*same as JMP GOT_OFFSET_HI but shorter) @@ -134,7 +132,6 @@ REPMATCH_OR_LARGE_OFFSET ; (*same as JMP GOT_OFFSET_HI but shorter) REPMATCH_OR_16_BIT ; rep-match or 16 bit offset - ;;ASL ; XYZ=111? BMI REP_MATCH ; reuse previous offset if so (rep-match) ; 110: handle 16 bit offset @@ -259,7 +256,6 @@ GETCOMBINEDBITS JSR GETNIBBLE ; get nibble into bits 0-3 (for offset bits 1-4) PLP ; merge Z bit as the carry bit (for offset bit 0) -COMBINEDBITZ ROL ; nibble -> bits 1-4; carry(!Z bit) -> bit 0 ; carry cleared DECOMPRESSION_DONE RTS diff --git a/Tools/unix/lzsa/asm/6502/decompress_faster_v1.asm b/Tools/unix/lzsa/asm/6502/decompress_faster_v1.asm index 93619070..1f65a40c 100644 --- a/Tools/unix/lzsa/asm/6502/decompress_faster_v1.asm +++ b/Tools/unix/lzsa/asm/6502/decompress_faster_v1.asm @@ -29,15 +29,6 @@ ; Decompression Options & Macros ; - ; - ; Save 6 bytes of code and 21 cycles by swapping the order - ; of bytes in the 16-bit length encoding? - ; - ; N.B. Setting this breaks compatibility with LZSA v1.2 - ; - -LZSA_SWAP_LEN16 = 0 - ; ; Choose size over space (within sane limits)? ; @@ -80,14 +71,6 @@ LZSA_SHORT_LZ = 1 LZSA_SHORT_LZ = 0 } - ; - ; Assume that we're decompessing from a large multi-bank - ; compressed data file, and that the next bank may need to - ; paged in when a page-boundary is crossed. - ; - -LZSA_FROM_BANK = 0 - ; ; Macro to increment the source pointer to the next page. ; @@ -95,14 +78,8 @@ LZSA_FROM_BANK = 0 ; has been crossed, and a new bank should be paged in. ; - !if LZSA_FROM_BANK { - !macro LZSA_INC_PAGE { - jsr lzsa1_next_page - } - } else { - !macro LZSA_INC_PAGE { + !macro LZSA_INC_PAGE { inc bits 1-4; carry(!Z bit) -> bit 0 ; carry cleared DECOMPRESSION_DONE RTS diff --git a/Tools/unix/lzsa/asm/65816/decompress_v1.asm b/Tools/unix/lzsa/asm/65816/decompress_v1.asm new file mode 100644 index 00000000..4754e553 --- /dev/null +++ b/Tools/unix/lzsa/asm/65816/decompress_v1.asm @@ -0,0 +1,281 @@ +; ----------------------------------------------------------------------------- +; Decompress raw LZSA1 block. Create one with lzsa -r +; +; in: +; * LZSA_SRC_LO/LZSA_SRC_HI/LZSA_SRC_BANK contain the compressed raw block address +; * LZSA_DST_LO/LZSA_DST_HI/LZSA_DST_BANK contain the destination buffer address +; +; out: +; * LZSA_DST_LO/LZSA_DST_HI/LZSA_DST_BANK contain the last decompressed byte address, +1 +; +; ----------------------------------------------------------------------------- +; Backward decompression is also supported, use lzsa -r -b +; To use it, also define BACKWARD_DECOMPRESS=1 before including this code! +; +; in: +; * LZSA_SRC_LO/LZSA_SRC_HI/LZSA_SRC_BANK must contain the address of the last byte of compressed data +; * LZSA_DST_LO/LZSA_DST_HI/LZSA_DST_BANK must contain the address of the last byte of the destination buffer +; +; out: +; * LZSA_DST_LO/LZSA_DST_HI/BANK contain the last decompressed byte address, -1 +; +; ----------------------------------------------------------------------------- +; +; Copyright (C) 2019-2020 Emmanuel Marty, Peter Ferrie +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. +; ----------------------------------------------------------------------------- + +!cpu 65816 +DECOMPRESS_LZSA1 + SEP #$30 +!as +!rs + LDY #$00 + +DECODE_TOKEN + JSR GETSRC ; read token byte: O|LLL|MMMM + PHA ; preserve token on stack + + AND #$70 ; isolate literals count + BEQ NO_LITERALS ; skip if no literals to copy + CMP #$70 ; LITERALS_RUN_LEN? + BNE PREPARE_COPY_LITERALS ; if not, count is directly embedded in token + + JSR GETSRC ; get extra byte of variable literals count + ; the carry is always set by the CMP above + ; GETSRC doesn't change it + SBC #$F9 ; (LITERALS_RUN_LEN) + BCC PREPARE_COPY_LITERALS_DIRECT + BEQ LARGE_VARLEN_LITERALS ; if adding up to zero, go grab 16-bit count + + JSR GETSRC ; get single extended byte of variable literals count + INY ; add 256 to literals count + BCS PREPARE_COPY_LITERALS_DIRECT ; (*like JMP PREPARE_COPY_LITERALS_DIRECT but shorter) + +LARGE_VARLEN_LITERALS ; handle 16 bits literals count + ; literals count = directly these 16 bits + JSR GETLARGESRC ; grab low 8 bits in X, high 8 bits in A + TAY ; put high 8 bits in Y + TXA + BCS PREPARE_COPY_LARGE_LITERALS ; (*like JMP PREPARE_COPY_LITERALS_DIRECT but shorter) + +PREPARE_COPY_LITERALS + TAX + LDA SHIFT_TABLE-1,X ; shift literals length into place + ; -1 because position 00 is reserved +PREPARE_COPY_LITERALS_DIRECT + TAX + +PREPARE_COPY_LARGE_LITERALS + BEQ COPY_LITERALS + INY + +COPY_LITERALS + JSR GETPUT ; copy one byte of literals + DEX + BNE COPY_LITERALS + DEY + BNE COPY_LITERALS + +NO_LITERALS + PLA ; retrieve token from stack + PHA ; preserve token again + BMI GET_LONG_OFFSET ; $80: 16 bit offset + + JSR GETSRC ; get 8 bit offset from stream in A + TAX ; save for later + LDA #$FF ; high 8 bits + BNE GOT_OFFSET ; go prepare match + ; (*like JMP GOT_OFFSET but shorter) + +SHORT_VARLEN_MATCHLEN + JSR GETSRC ; get single extended byte of variable match len + INY ; add 256 to match length + +PREPARE_COPY_MATCH + TAX +PREPARE_COPY_MATCH_Y + TXA + BEQ COPY_MATCH_LOOP + INY + +COPY_MATCH_LOOP + LDA $AAAAAA ; get one byte of backreference + JSR PUTDST ; copy to destination + + REP #$20 +!ifdef BACKWARD_DECOMPRESS { + + ; Backward decompression -- put backreference bytes backward + + DEC COPY_MATCH_LOOP+1 + +} else { + + ; Forward decompression -- put backreference bytes forward + + INC COPY_MATCH_LOOP+1 + +} + SEP #$20 + + DEX + BNE COPY_MATCH_LOOP + DEY + BNE COPY_MATCH_LOOP + BEQ DECODE_TOKEN ; (*like JMP DECODE_TOKEN but shorter) + +GET_LONG_OFFSET ; handle 16 bit offset: + JSR GETLARGESRC ; grab low 8 bits in X, high 8 bits in A + +GOT_OFFSET + +!ifdef BACKWARD_DECOMPRESS { + + ; Backward decompression - substract match offset + + STA OFFSHI ; store high 8 bits of offset + STX OFFSLO + + SEC ; substract dest - match offset + REP #$20 +!al + LDA PUTDST+1 +OFFSLO = *+1 +OFFSHI = *+2 + SBC #$AAAA ; 16 bits + STA COPY_MATCH_LOOP+1 ; store back reference address + SEP #$20 +!as + SEC + +} else { + + ; Forward decompression - add match offset + + STA OFFSHI ; store high 8 bits of offset + TXA + + CLC ; add dest + match offset + ADC PUTDST+1 ; low 8 bits + STA COPY_MATCH_LOOP+1 ; store back reference address +OFFSHI = *+1 + LDA #$AA ; high 8 bits + + ADC PUTDST+2 + STA COPY_MATCH_LOOP+2 ; store high 8 bits of address + +} + + LDA PUTDST+3 ; bank + STA COPY_MATCH_LOOP+3 ; store back reference address + + PLA ; retrieve token from stack again + AND #$0F ; isolate match len (MMMM) + ADC #$02 ; plus carry which is always set by the high ADC + CMP #$12 ; MATCH_RUN_LEN? + BCC PREPARE_COPY_MATCH ; if not, count is directly embedded in token + + JSR GETSRC ; get extra byte of variable match length + ; the carry is always set by the CMP above + ; GETSRC doesn't change it + SBC #$EE ; add MATCH_RUN_LEN and MIN_MATCH_SIZE to match length + BCC PREPARE_COPY_MATCH + BNE SHORT_VARLEN_MATCHLEN + + ; Handle 16 bits match length + JSR GETLARGESRC ; grab low 8 bits in X, high 8 bits in A + TAY ; put high 8 bits in Y + ; large match length with zero high byte? + BNE PREPARE_COPY_MATCH_Y ; if not, continue + +DECOMPRESSION_DONE + RTS + +SHIFT_TABLE + !BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + !BYTE $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01 + !BYTE $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02 + !BYTE $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03 + !BYTE $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 + !BYTE $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05 + !BYTE $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06 + !BYTE $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07 + +!ifdef BACKWARD_DECOMPRESS { + + ; Backward decompression -- get and put bytes backward + +GETPUT + JSR GETSRC +PUTDST +LZSA_DST_LO = *+1 +LZSA_DST_HI = *+2 +LZSA_DST_BANK = *+3 + STA $AAAAAA + REP #$20 + DEC PUTDST+1 + SEP #$20 + RTS + +GETLARGESRC + JSR GETSRC ; grab low 8 bits + TAX ; move to X + ; fall through grab high 8 bits + +GETSRC +LZSA_SRC_LO = *+1 +LZSA_SRC_HI = *+2 +LZSA_SRC_BANK = *+3 + LDA $AAAAAA + REP #$20 + DEC GETSRC+1 + SEP #$20 + RTS + +} else { + + ; Forward decompression -- get and put bytes forward + +GETPUT + JSR GETSRC +PUTDST +LZSA_DST_LO = *+1 +LZSA_DST_HI = *+2 +LZSA_DST_BANK = *+3 + STA $AAAAAA + REP #$20 + INC PUTDST+1 + SEP #$20 + RTS + +GETLARGESRC + JSR GETSRC ; grab low 8 bits + TAX ; move to X + ; fall through grab high 8 bits + +GETSRC +LZSA_SRC_LO = *+1 +LZSA_SRC_HI = *+2 +LZSA_SRC_BANK = *+3 + LDA $AAAAAA + REP #$20 + INC GETSRC+1 + SEP #$20 + RTS +} diff --git a/Tools/unix/lzsa/asm/65816/decompress_v2.asm b/Tools/unix/lzsa/asm/65816/decompress_v2.asm new file mode 100644 index 00000000..08c2ac8f --- /dev/null +++ b/Tools/unix/lzsa/asm/65816/decompress_v2.asm @@ -0,0 +1,338 @@ +; ----------------------------------------------------------------------------- +; Decompress raw LZSA2 block. +; Create one with lzsa -r -f2 +; +; in: +; * LZSA_SRC_LO/LZSA_SRC_HI/LZSA_SRC_BANK contain the compressed raw block address +; * LZSA_DST_LO/LZSA_DST_HI/LZSA_DST_BANK contain the destination buffer address +; +; out: +; * LZSA_DST_LO/LZSA_DST_HI/LZSA_DST_BANK contain the last decompressed byte address, +1 +; +; ----------------------------------------------------------------------------- +; Backward decompression is also supported, use lzsa -r -b -f2 +; To use it, also define BACKWARD_DECOMPRESS=1 before including this code! +; +; in: +; * LZSA_SRC_LO/LZSA_SRC_HI/LZSA_SRC_BANK must contain the address of the last byte of compressed data +; * LZSA_DST_LO/LZSA_DST_HI/LZSA_DST_BANK must contain the address of the last byte of the destination buffer +; +; out: +; * LZSA_DST_LO/LZSA_DST_HI/BANK contain the last decompressed byte address, -1 +; +; ----------------------------------------------------------------------------- +; +; Copyright (C) 2019-2020 Emmanuel Marty, Peter Ferrie +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. +; ----------------------------------------------------------------------------- + +!cpu 65816 +NIBCOUNT = $FC ; zero-page location for temp offset + +DECOMPRESS_LZSA2 + SEP #$30 +!as +!rs + LDY #$00 + STY NIBCOUNT + +DECODE_TOKEN + JSR GETSRC ; read token byte: XYZ|LL|MMM + PHA ; preserve token on stack + + AND #$18 ; isolate literals count (LL) + BEQ NO_LITERALS ; skip if no literals to copy + CMP #$18 ; LITERALS_RUN_LEN_V2? + BCC PREPARE_COPY_LITERALS ; if less, count is directly embedded in token + + JSR GETNIBBLE ; get extra literals length nibble + ; add nibble to len from token + ADC #$02 ; (LITERALS_RUN_LEN_V2) minus carry + CMP #$12 ; LITERALS_RUN_LEN_V2 + 15 ? + BCC PREPARE_COPY_LITERALS_DIRECT ; if less, literals count is complete + + JSR GETSRC ; get extra byte of variable literals count + ; the carry is always set by the CMP above + ; GETSRC doesn't change it + SBC #$EE ; overflow? + BRA PREPARE_COPY_LITERALS_DIRECT + +PREPARE_COPY_LITERALS_LARGE + ; handle 16 bits literals count + ; literals count = directly these 16 bits + JSR GETLARGESRC ; grab low 8 bits in X, high 8 bits in A + TAY ; put high 8 bits in Y + BCS PREPARE_COPY_LITERALS_HIGH ; (*same as JMP PREPARE_COPY_LITERALS_HIGH but shorter) + +PREPARE_COPY_LITERALS + LSR ; shift literals count into place + LSR + LSR + +PREPARE_COPY_LITERALS_DIRECT + TAX + BCS PREPARE_COPY_LITERALS_LARGE ; if so, literals count is large + +PREPARE_COPY_LITERALS_HIGH + TXA + BEQ COPY_LITERALS + INY + +COPY_LITERALS + JSR GETPUT ; copy one byte of literals + DEX + BNE COPY_LITERALS + DEY + BNE COPY_LITERALS + +NO_LITERALS + PLA ; retrieve token from stack + PHA ; preserve token again + ASL + BCS REPMATCH_OR_LARGE_OFFSET ; 1YZ: rep-match or 13/16 bit offset + + ASL ; 0YZ: 5 or 9 bit offset + BCS OFFSET_9_BIT + + ; 00Z: 5 bit offset + + LDX #$FF ; set offset bits 15-8 to 1 + + JSR GETCOMBINEDBITS ; rotate Z bit into bit 0, read nibble for bits 4-1 + ORA #$E0 ; set bits 7-5 to 1 + BNE GOT_OFFSET_LO ; go store low byte of match offset and prepare match + +OFFSET_9_BIT ; 01Z: 9 bit offset + ;;ASL ; shift Z (offset bit 8) in place + ROL + ROL + AND #$01 + EOR #$FF ; set offset bits 15-9 to 1 + BNE GOT_OFFSET_HI ; go store high byte, read low byte of match offset and prepare match + ; (*same as JMP GOT_OFFSET_HI but shorter) + +REPMATCH_OR_LARGE_OFFSET + ASL ; 13 bit offset? + BCS REPMATCH_OR_16_BIT ; handle rep-match or 16-bit offset if not + + ; 10Z: 13 bit offset + + JSR GETCOMBINEDBITS ; rotate Z bit into bit 8, read nibble for bits 12-9 + ADC #$DE ; set bits 15-13 to 1 and substract 2 (to substract 512) + BNE GOT_OFFSET_HI ; go store high byte, read low byte of match offset and prepare match + ; (*same as JMP GOT_OFFSET_HI but shorter) + +REPMATCH_OR_16_BIT ; rep-match or 16 bit offset + ;;ASL ; XYZ=111? + BMI REP_MATCH ; reuse previous offset if so (rep-match) + + ; 110: handle 16 bit offset + JSR GETSRC ; grab high 8 bits +GOT_OFFSET_HI + TAX + JSR GETSRC ; grab low 8 bits +GOT_OFFSET_LO + STA OFFSLO ; store low byte of match offset + STX OFFSHI ; store high byte of match offset + +REP_MATCH +!ifdef BACKWARD_DECOMPRESS { + + ; Backward decompression - substract match offset + + SEC ; add dest + match offset + REP #$20 +!al + LDA PUTDST+1 ; 16 bits +OFFSLO = *+1 +OFFSHI = *+2 + SBC #$AAAA + STA COPY_MATCH_LOOP+1 ; store back reference address + SEP #$20 +!as + SEC + +} else { + + ; Forward decompression - add match offset + + CLC ; add dest + match offset + REP #$20 +!al + LDA PUTDST+1 ; 16 bits +OFFSLO = *+1 +OFFSHI = *+2 + ADC #$AAAA + STA COPY_MATCH_LOOP+1 ; store back reference address + SEP #$20 +!as +} + + LDA PUTDST+3 ; bank + STA COPY_MATCH_LOOP+3 ; store back reference address + + PLA ; retrieve token from stack again + AND #$07 ; isolate match len (MMM) + ADC #$01 ; add MIN_MATCH_SIZE_V2 and carry + CMP #$09 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2? + BCC PREPARE_COPY_MATCH ; if less, length is directly embedded in token + + JSR GETNIBBLE ; get extra match length nibble + ; add nibble to len from token + ADC #$08 ; (MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2) minus carry + CMP #$18 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15? + BCC PREPARE_COPY_MATCH ; if less, match length is complete + + JSR GETSRC ; get extra byte of variable match length + ; the carry is always set by the CMP above + ; GETSRC doesn't change it + SBC #$E8 ; overflow? + +PREPARE_COPY_MATCH + TAX + BCC PREPARE_COPY_MATCH_Y ; if not, the match length is complete + BEQ DECOMPRESSION_DONE ; if EOD code, bail + + ; Handle 16 bits match length + JSR GETLARGESRC ; grab low 8 bits in X, high 8 bits in A + TAY ; put high 8 bits in Y + +PREPARE_COPY_MATCH_Y + TXA + BEQ COPY_MATCH_LOOP + INY + +COPY_MATCH_LOOP + LDA $AAAAAA ; get one byte of backreference + JSR PUTDST ; copy to destination + + REP #$20 +!ifdef BACKWARD_DECOMPRESS { + + ; Backward decompression -- put backreference bytes backward + + DEC COPY_MATCH_LOOP+1 + +} else { + + ; Forward decompression -- put backreference bytes forward + + INC COPY_MATCH_LOOP+1 + +} + SEP #$20 + + DEX + BNE COPY_MATCH_LOOP + DEY + BNE COPY_MATCH_LOOP + JMP DECODE_TOKEN + +GETCOMBINEDBITS + EOR #$80 + ASL + PHP + + JSR GETNIBBLE ; get nibble into bits 0-3 (for offset bits 1-4) + PLP ; merge Z bit as the carry bit (for offset bit 0) +COMBINEDBITZ + ROL ; nibble -> bits 1-4; carry(!Z bit) -> bit 0 ; carry cleared +DECOMPRESSION_DONE + RTS + +GETNIBBLE +NIBBLES = *+1 + LDA #$AA + LSR NIBCOUNT + BCC NEED_NIBBLES + AND #$0F ; isolate low 4 bits of nibble + RTS + +NEED_NIBBLES + INC NIBCOUNT + JSR GETSRC ; get 2 nibbles + STA NIBBLES + LSR + LSR + LSR + LSR + SEC + RTS + +!ifdef BACKWARD_DECOMPRESS { + + ; Backward decompression -- get and put bytes backward + +GETPUT + JSR GETSRC +PUTDST +LZSA_DST_LO = *+1 +LZSA_DST_HI = *+2 +LZSA_DST_BANK = *+3 + STA $AAAAAA + REP #$20 + DEC PUTDST+1 + SEP #$20 + RTS + +GETLARGESRC + JSR GETSRC ; grab low 8 bits + TAX ; move to X + ; fall through grab high 8 bits + +GETSRC +LZSA_SRC_LO = *+1 +LZSA_SRC_HI = *+2 +LZSA_SRC_BANK = *+3 + LDA $AAAAAA + REP #$20 + DEC GETSRC+1 + SEP #$20 + RTS + +} else { + + ; Forward decompression -- get and put bytes forward + +GETPUT + JSR GETSRC +PUTDST +LZSA_DST_LO = *+1 +LZSA_DST_HI = *+2 +LZSA_DST_BANK = *+3 + STA $AAAAAA + REP #$20 + INC PUTDST+1 + SEP #$20 + RTS + +GETLARGESRC + JSR GETSRC ; grab low 8 bits + TAX ; move to X + ; fall through grab high 8 bits + +GETSRC +LZSA_SRC_LO = *+1 +LZSA_SRC_HI = *+2 +LZSA_SRC_BANK = *+3 + LDA $AAAAAA + REP #$20 + INC GETSRC+1 + SEP #$20 + RTS +} diff --git a/Tools/unix/lzsa/asm/6809/unlzsa1-6309.s b/Tools/unix/lzsa/asm/6809/unlzsa1-6309.s new file mode 100644 index 00000000..5866e8db --- /dev/null +++ b/Tools/unix/lzsa/asm/6809/unlzsa1-6309.s @@ -0,0 +1,90 @@ +; unlzsa1-6309.s - Hitachi 6309 decompression routine for raw LZSA1 - 92 bytes +; compress with lzsa -f1 -r +; +; in: x = start of compressed data +; y = start of decompression buffer +; out: y = end of decompression buffer + 1 +; +; Copyright (C) 2020 Emmanuel Marty, Doug Masten +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. + +decompress_lzsa1 equ lz1token + +lz1bigof lda ,x+ ; O set: load MSB 16-bit (negative, signed) offest +lz1gotof leau d,y ; put backreference start address in U (dst+offset) + + ldd #$000f ; clear MSB match length and set mask for MMMM + andb ,s+ ; isolate MMMM (embedded match length) in token + addb #$03 ; add MIN_MATCH_SIZE + cmpb #$12 ; MATCH_RUN_LEN? + bne lz1gotln ; no, we have the full match length, go copy + + addb ,x+ ; add extra match length byte + MIN_MATCH_SIZE + MATCH_RUN_LEN + bcc lz1gotln ; if no overflow, we have the full length + bne lz1midln + + ldb ,x+ ; load 16-bit len in D (low part in B, high in A) + lda ,x+ ; (little endian) + bne lz1gotln ; check if we hit EOD (16-bit length = 0) + tstb + bne lz1gotln ; go copy matched bytes if not + + rts ; done, bail + +lz1midln tfr b,a ; copy high part of len into A + ldb ,x+ ; grab low 8 bits of len in B + +lz1gotln tfr d,w ; set W with match length for TFM instruction + tfm u+,y+ ; copy match bytes + +lz1token ldb ,x+ ; load next token into B: O|LLL|MMMM + pshs b ; save it + + andb #$70 ; isolate LLL (embedded literals count) in B + beq lz1nolt ; skip if no literals + cmpb #$70 ; LITERALS_RUN_LEN? + bne lz1declt ; if not, we have the complete count, go unshift + + ldb ,x+ ; load extra literals count byte + addb #$07 ; add LITERALS_RUN_LEN + bcc lz1gotla ; if no overflow, we got the complete count, copy + bne lz1midlt + + ldb ,x+ ; load low 8 bits of little-endian literals count + lda ,x+ ; load high 8 bits of literal count + bra lz1gotlt ; we now have the complete count, go copy + +lz1midlt tfr b,a ; copy high part of literals count into A + ldb ,x+ ; load low 8 bits of literals count + bra lz1gotlt ; we now have the complete count, go copy + +lz1declt lsrb ; shift literals count into place + lsrb + lsrb + lsrb + +lz1gotla clra ; clear A (high part of literals count) +lz1gotlt tfr d,w ; set W with literals count for TFM instruction + tfm x+,y+ ; copy literal bytes + +lz1nolt ldb ,x+ ; load either 8-bit or LSB 16-bit offset (negative, signed) + lda ,s ; get token again, don't pop it from the stack + bmi lz1bigof ; test O bit (small or large offset) + + lda #$ff ; set high 8 bits + bra lz1gotof diff --git a/Tools/unix/lzsa/asm/6809/unlzsa1.s b/Tools/unix/lzsa/asm/6809/unlzsa1.s new file mode 100644 index 00000000..559a3032 --- /dev/null +++ b/Tools/unix/lzsa/asm/6809/unlzsa1.s @@ -0,0 +1,102 @@ +; unlzsa1.s - 6809 decompression routine for raw LZSA1 - 110 bytes +; compress with lzsa -r +; +; in: x = start of compressed data +; y = start of decompression buffer +; out: y = end of decompression buffer + 1 +; +; Copyright (C) 2020 Emmanuel Marty +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. + +decompress_lzsa1 equ lz1token + +lz1bigof lda ,x+ ; O set: load MSB 16-bit (negative, signed) offest +lz1gotof leau d,y ; put backreference start address in U (dst+offset) + + ldd #$000f ; clear MSB match length and set mask for MMMM + andb ,s+ ; isolate MMMM (embedded match length) in token + addb #$03 ; add MIN_MATCH_SIZE + cmpb #$12 ; MATCH_RUN_LEN? + bne lz1gotln ; no, we have the full match length, go copy + + addb ,x+ ; add extra match length byte + MIN_MATCH_SIZE + MATCH_RUN_LEN + bcc lz1gotln ; if no overflow, we have the full length + bne lz1midln + + ldb ,x+ ; load 16-bit len in D (low part in B, high in A) + lda ,x+ ; (little endian) + bne lz1gotln ; check if we hit EOD (16-bit length = 0) + tstb + bne lz1gotln ; go copy matched bytes if not + + rts ; done, bail + +lz1midln tfr b,a ; copy high part of len into A + ldb ,x+ ; grab low 8 bits of len in B + +lz1gotln pshs x ; save source compressed data pointer + tfr d,x ; copy match length to X + +lz1cpymt lda ,u+ ; copy matched byte + sta ,y+ + leax -1,x ; decrement X + bne lz1cpymt ; loop until all matched bytes are copied + + puls x ; restore source compressed data pointer + +lz1token ldb ,x+ ; load next token into B: O|LLL|MMMM + pshs b ; save it + + andb #$70 ; isolate LLL (embedded literals count) in B + beq lz1nolt ; skip if no literals + cmpb #$70 ; LITERALS_RUN_LEN? + bne lz1declt ; if not, we have the complete count, go unshift + + ldb ,x+ ; load extra literals count byte + addb #$07 ; add LITERALS_RUN_LEN + bcc lz1gotla ; if no overflow, we got the complete count, copy + bne lz1midlt + + ldb ,x+ ; load low 8 bits of little-endian literals count + lda ,x+ ; load high 8 bits of literal count + bra lz1gotlt ; we now have the complete count, go copy + +lz1midlt tfr b,a ; copy high part of literals count into A + ldb ,x+ ; load low 8 bits of literals count + bra lz1gotlt ; we now have the complete count, go copy + +lz1declt lsrb ; shift literals count into place + lsrb + lsrb + lsrb +lz1gotla clra ; clear A (high part of literals count) + +lz1gotlt leau ,x + tfr d,x ; transfer 16-bit count into X +lz1cpylt lda ,u+ ; copy literal byte + sta ,y+ + leax -1,x ; decrement X and update Z flag + bne lz1cpylt ; loop until all literal bytes are copied + leax ,u + +lz1nolt ldb ,x+ ; load either 8-bit or LSB 16-bit offset (negative, signed) + lda ,s ; get token again, don't pop it from the stack + bmi lz1bigof ; test O bit (small or large offset) + + lda #$ff ; set high 8 bits + bra lz1gotof diff --git a/Tools/unix/lzsa/asm/6809/unlzsa1b-6309.s b/Tools/unix/lzsa/asm/6809/unlzsa1b-6309.s new file mode 100644 index 00000000..60780856 --- /dev/null +++ b/Tools/unix/lzsa/asm/6809/unlzsa1b-6309.s @@ -0,0 +1,92 @@ +; unlzsa1-6309.s - H6309 backward decompressor for raw LZSA1 - 97 bytes +; compress with lzsa -f1 -r -b +; +; in: x = last byte of compressed data +; y = last byte of decompression buffer +; out: y = first byte of decompressed data +; +; Copyright (C) 2020 Emmanuel Marty, Doug Masten +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. + +decompress_lzsa1 + leax 1,x + bra lz1token + +lz1bigof ldd ,--x ; O set: load long 16-bit (negative, signed) offest +lz1gotof negd ; reverse sign of offset in D + leau d,y ; put backreference start address in U (dst+offset) + + ldd #$000f ; clear MSB match length and set mask for MMMM + andb ,s+ ; isolate MMMM (embedded match length) in token + addb #$03 ; add MIN_MATCH_SIZE + cmpb #$12 ; MATCH_RUN_LEN? + bne lz1gotln ; no, we have the full match length, go copy + + addb ,-x ; add extra match length byte + MIN_MATCH_SIZE + MATCH_RUN_LEN + bcc lz1gotln ; if no overflow, we have the full length + bne lz1midln + + ldd ,--x ; load 16-bit len in D (low part in B, high in A) + bne lz1gotln ; check if we hit EOD (16-bit length = 0) + + leay 1,y ; adjust pointer to first byte of decompressed data + rts ; done, bail + +lz1midln tfr b,a ; copy high part of len into A + ldb ,-x ; grab low 8 bits of len in B + +lz1gotln tfr d,w ; set W with match length for TFM instruction + tfm u-,y- ; copy match bytes + +lz1token ldb ,-x ; load next token into B: O|LLL|MMMM + pshs b ; save it + + andb #$70 ; isolate LLL (embedded literals count) in B + beq lz1nolt ; skip if no literals + cmpb #$70 ; LITERALS_RUN_LEN? + bne lz1declt ; if not, we have the complete count, go unshift + + ldb ,-x ; load extra literals count byte + addb #$07 ; add LITERALS_RUN_LEN + bcc lz1gotla ; if no overflow, we got the complete count, copy + bne lz1midlt + + ldd ,--x ; load 16 bit count in D (low part in B, high in A) + bra lz1gotlt ; we now have the complete count, go copy + +lz1midlt tfr b,a ; copy high part of literals count into A + ldb ,-x ; load low 8 bits of literals count + bra lz1gotlt ; we now have the complete count, go copy + +lz1declt lsrb ; shift literals count into place + lsrb + lsrb + lsrb + +lz1gotla clra ; clear A (high part of literals count) +lz1gotlt tfr d,w ; set W with literals count for TFM instruction + leax -1,x ; tfm is post-decrement + tfm x-,y- ; copy literal bytes + leax 1,x + +lz1nolt ldb ,s ; get token again, don't pop it from the stack + bmi lz1bigof ; test O bit (small or large offset) + + ldb ,-x ; load either 8-bit or LSB 16-bit offset (negative, signed) + lda #$ff ; set high 8 bits + bra lz1gotof diff --git a/Tools/unix/lzsa/asm/6809/unlzsa1b.s b/Tools/unix/lzsa/asm/6809/unlzsa1b.s new file mode 100644 index 00000000..ada6dcc9 --- /dev/null +++ b/Tools/unix/lzsa/asm/6809/unlzsa1b.s @@ -0,0 +1,105 @@ +; unlzsa1b.s - 6809 backward decompression routine for raw LZSA1 - 113 bytes +; compress with lzsa -r -b +; +; in: x = last byte of compressed data +; y = last byte of decompression buffer +; out: y = first byte of decompressed data +; +; Copyright (C) 2020 Emmanuel Marty +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. + +decompress_lzsa1 + leax 1,x + leay 1,y + bra lz1token + +lz1bigof ldd ,--x ; O set: load long 16 bit (negative, signed) offset +lz1gotof nega ; reverse sign of offset in D + negb + sbca #0 + leau d,y ; put backreference start address in U (dst+offset) + + ldd #$000f ; clear MSB match length and set mask for MMMM + andb ,s+ ; isolate MMMM (embedded match length) in token + + addb #$03 ; add MIN_MATCH_SIZE + cmpb #$12 ; MATCH_RUN_LEN? + bne lz1gotln ; no, we have the full match length, go copy + + addb ,-x ; add extra match length byte + MIN_MATCH_SIZE + MATCH_RUN_LEN + bcc lz1gotln ; if no overflow, we have the full length + bne lz1midln + + ldd ,--x ; load 16-bit len in D (low part in B, high in A) + bne lz1gotln ; check if we hit EOD (16-bit length = 0) + + rts ; done, bail + +lz1midln tfr b,a ; copy high part of len into A + ldb ,-x ; grab low 8 bits of len in B + +lz1gotln pshs x ; save source compressed data pointer + tfr d,x ; copy match length to X + +lz1cpymt lda ,-u ; copy matched byte + sta ,-y + leax -1,x ; decrement X + bne lz1cpymt ; loop until all matched bytes are copied + + puls x ; restore source compressed data pointer + +lz1token ldb ,-x ; load next token into B: O|LLL|MMMM + pshs b ; save it + + andb #$70 ; isolate LLL (embedded literals count) in B + beq lz1nolt ; skip if no literals + cmpb #$70 ; LITERALS_RUN_LEN? + bne lz1declt ; if not, we have the complete count, go unshift + + ldb ,-x ; load extra literals count byte + addb #$07 ; add LITERALS_RUN_LEN + bcc lz1gotla ; if no overflow, we got the complete count, copy + bne lz1midlt + + ldd ,--x ; load 16 bit count in D (low part in B, high in A) + bra lz1gotlt ; we now have the complete count, go copy + +lz1midlt tfr b,a ; copy high part of literals count into A + ldb ,-x ; load low 8 bits of literals count + bra lz1gotlt ; we now have the complete count, go copy + +lz1declt lsrb ; shift literals count into place + lsrb + lsrb + lsrb + +lz1gotla clra ; clear A (high part of literals count) +lz1gotlt leau ,x + tfr d,x ; transfer 16-bit count into X +lz1cpylt lda ,-u ; copy literal byte + sta ,-y + leax -1,x ; decrement X and update Z flag + bne lz1cpylt ; loop until all literal bytes are copied + leax ,u + +lz1nolt ldb ,s ; get token again, don't pop it from the stack + bmi lz1bigof ; test O bit (small or large offset) + + ldb ,-x ; O clear: load 8 bit (negative, signed) offset + lda #$ff ; set high 8 bits + bra lz1gotof diff --git a/Tools/unix/lzsa/asm/6809/unlzsa2-6309.s b/Tools/unix/lzsa/asm/6809/unlzsa2-6309.s new file mode 100644 index 00000000..17970d8b --- /dev/null +++ b/Tools/unix/lzsa/asm/6809/unlzsa2-6309.s @@ -0,0 +1,129 @@ +; unlzsa2-6309.s - Hitachi 6309 decompression routine for raw LZSA2 - 150 bytes +; compress with lzsa -f2 -r +; +; in: x = start of compressed data +; y = start of decompression buffer +; out: y = end of decompression buffer + 1 +; +; Copyright (C) 2020 Emmanuel Marty, Doug Masten +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. + +decompress_lzsa2 + clr lz2nibct ; reset nibble available flag + bra lz2token + +lz2nibct fcb 0 ; nibble ready flag + +lz2replg lslb ; push token's Y flag bit into carry + bcs lz2rep16 ; if token's Y bit is set, rep or 16 bit offset + + sex ; push token's Z flag bit into reg A + bsr lz2nibl ; get offset nibble in B + lsla ; push token's Z flag bit into carry + rolb ; shift Z flag from carry into bit 0 of B + eorb #$e1 ; set bits 13-15 of offset, reverse bit 8 + tfr b,a ; copy bits 8-15 of offset into A + suba #$02 ; substract 512 from offset + ldb ,x+ ; load low 8 bits of (negative, signed) offset + bra lz2gotof + +lz2rep16 bmi lz2repof ; if token's Z flag bit is set, rep match + ldd ,x++ ; load high then low 8 bits of offset + +lz2gotof std lz2moff+2 ; store match offset + +lz2repof ldd #$0007 ; clear MSB match length and set mask for MMM + andb ,u ; isolate MMM (embedded match length) in token +lz2moff leau $aaaa,y ; put backreference start address in U (dst+offset) + addb #$02 ; add MIN_MATCH_SIZE_V2 + cmpb #$09 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2? + bne lz2gotln ; no, we have the full match length, go copy + + bsr lz2nibl ; get offset nibble in B + addb #$09 ; add MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + cmpb #$18 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15? + bne lz2gotln ; if not, we have the full match length, go copy + + addb ,x+ ; add extra length byte + MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15 + bcc lz2gotln ; if no overflow, we have the full length + beq lz2done ; detect EOD code + + ldb ,x+ ; load 16-bit len in D (low part in B, high in A) + lda ,x+ ; (little endian) + +lz2gotln tfr d,w ; set W with match count for TFM instruction + tfm u+,y+ ; copy match bytes + +lz2token tfr x,u ; save token address + ldb ,x+ ; load next token into B: XYZ|LL|MMM + andb #$18 ; isolate LL (embedded literals count) in B + beq lz2nolt ; skip if no literals + cmpb #$18 ; LITERALS_RUN_LEN_V2? + bne lz2declt ; if not, we have the complete count, go unshift + + bsr lz2nibl ; get extra literals length nibble in B + addb #$03 ; add LITERALS_RUN_LEN_V2 + cmpb #$12 ; LITERALS_RUN_LEN_V2 + 15 ? + bne lz2gotla ; if not, we have the full literals count, go copy + + addb ,x+ ; add extra literals count byte + LITERALS_RUN_LEN + 15 + bcc lz2gotla ; if no overflow, we got the complete count, copy + + ldb ,x+ ; load low 8 bits of little-endian literals count + lda ,x+ ; load high 8 bits of literal count + bra lz2gotlt ; we now have the complete count, go copy + +lz2declt lsrb ; shift literals count into place + lsrb + lsrb +lz2gotla clra ; clear A (high part of literals count) + +lz2gotlt tfr d,w ; set W with literals count for TFM instruction + tfm x+,y+ ; copy literal bytes + +lz2nolt ldb ,u ; get token again + lslb ; push token's X flag bit into carry + bcs lz2replg ; if token's X bit is set, rep or large offset + + lslb ; push token's Y flag bit into carry + sex ; push token's Z flag bit into reg A (carry flag is not effected) + bcs lz2offs9 ; if token's Y bit is set, 9 bits offset + + bsr lz2nibl ; get offset nibble in B + lsla ; retrieve token's Z flag bit and push into carry + rolb ; shift Z flag from carry into bit 0 of B + eorb #$e1 ; set bits 5-7 of offset, reverse bit 0 + sex ; set bits 8-15 of offset to $FF + bra lz2gotof + +lz2offs9 deca ; set bits 9-15 of offset, reverse bit 8 + ldb ,x+ ; load low 8 bits of (negative, signed) offset + bra lz2gotof + +lz2nibl ldb #$aa + com lz2nibct ; nibble ready? + bpl lz2gotnb + + ldb ,x+ ; load two nibbles + stb lz2nibl+1 ; store nibble for next time (low 4 bits) + lsrb ; shift 4 high bits of nibble down + lsrb + lsrb + lsrb +lz2gotnb andb #$0f ; only keep low 4 bits +lz2done rts diff --git a/Tools/unix/lzsa/asm/6809/unlzsa2.s b/Tools/unix/lzsa/asm/6809/unlzsa2.s new file mode 100644 index 00000000..a620cadb --- /dev/null +++ b/Tools/unix/lzsa/asm/6809/unlzsa2.s @@ -0,0 +1,146 @@ +; unlzsa2.s - 6809 decompression routine for raw LZSA2 - 169 bytes +; compress with lzsa -f2 -r +; +; in: x = start of compressed data +; y = start of decompression buffer +; out: y = end of decompression buffer + 1 +; +; Copyright (C) 2020 Emmanuel Marty +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. + +decompress_lzsa2 + clr +; +; in: x = last byte of compressed data +; y = last byte of decompression buffer +; out: y = first byte of decompressed data +; +; Copyright (C) 2020 Emmanuel Marty, Doug Masten +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. + +decompress_lzsa2 + clr lz2nibct ; reset nibble available flag + leax 1,x ; adjust compressed data pointer + bra lz2token + +lz2nibct fcb 0 ; nibble ready flag + +lz2replg lslb ; push token's Y flag bit into carry + bcs lz2rep16 ; if token's Y bit is set, rep or 16 bit offset + + sex ; push token's Z flag bit into reg A + bsr lz2nibl ; get offset nibble in B + lsla ; push token's Z flag bit into carry + rolb ; shift Z flag from carry into bit 0 of B + eorb #$e1 ; set bits 13-15 of offset, reverse bit 8 + tfr b,a ; copy bits 8-15 of offset into A + suba #$02 ; substract 512 from offset + bra lz2lowof + +lz2rep16 bmi lz2repof ; if token's Z flag bit is set, rep match + lda ,-x ; load high 8 bits of (negative, signed) offset +lz2lowof ldb ,-x ; load low 8 bits of offset + +lz2gotof negd ; reverse sign of offset in D + std lz2moff+2 ; store match offset + +lz2repof ldd #$0007 ; clear MSB match length and set mask for MMM + andb ,u ; isolate MMM (embedded match length) in token +lz2moff leau $aaaa,y ; put backreference start address in U (dst+offset) + addb #$02 ; add MIN_MATCH_SIZE_V2 + cmpb #$09 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2? + bne lz2gotln ; no, we have the full match length, go copy + + bsr lz2nibl ; get offset nibble in B + addb #$09 ; add MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + cmpb #$18 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15? + bne lz2gotln ; if not, we have the full match length, go copy + + addb ,-x ; add extra length byte + MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15 + bcc lz2gotln ; if no overflow, we have the full length + beq lz2done ; detect EOD code + + ldd ,--x ; load 16-bit len in D (low part in B, high in A) + +lz2gotln tfr d,w ; set W with match count for TFM instruction + tfm u-,y- ; copy match bytes + +lz2token ldb ,-x ; load next token into B: XYZ|LL|MMM + tfr x,u ; save token address + andb #$18 ; isolate LL (embedded literals count) in B + beq lz2nolt ; skip if no literals + cmpb #$18 ; LITERALS_RUN_LEN_V2? + bne lz2declt ; if not, we have the complete count, go unshift + + bsr lz2nibl ; get extra literals length nibble in B + addb #$03 ; add LITERALS_RUN_LEN_V2 + cmpb #$12 ; LITERALS_RUN_LEN_V2 + 15 ? + bne lz2gotla ; if not, we have the full literals count, go copy + + addb ,-x ; add extra literals count byte + LITERALS_RUN_LEN + 15 + bcc lz2gotla ; if no overflow, we got the complete count, copy + + ldd ,--x ; load 16 bit count in D (low part in B, high in A) + bra lz2gotlt ; we now have the complete count, go copy + +lz2nibl com lz2nibct ; nibble ready? + bpl lz2gotnb + + ldb ,-x ; load two nibbles + stb lz2gotnb+1 ; store nibble for next time (low 4 bits) + lsrb ; shift 4 high bits of nibble down + lsrb + lsrb + lsrb + rts + +lz2declt lsrb ; shift literals count into place + lsrb + lsrb +lz2gotla clra ; clear A (high part of literals count) + +lz2gotlt tfr d,w ; set W with literals count for TFM instruction + leax -1,x ; tfm is post-decrement + tfm x-,y- ; copy literal bytes + leax 1,x + +lz2nolt ldb ,u ; get token again + lslb ; push token's X flag bit into carry + bcs lz2replg ; if token's X bit is set, rep or large offset + + lslb ; push token's Y flag bit into carry + sex ; push token's Z flag bit into reg A (carry flag is not effected) + bcs lz2offs9 ; if token's Y bit is set, 9 bits offset + + bsr lz2nibl ; get offset nibble in B + lsla ; retrieve token's Z flag bit and push into carry + rolb ; shift Z flag from carry into bit 0 of B + eorb #$e1 ; set bits 5-7 of offset, reverse bit 0 + sex ; set bits 8-15 of offset to $FF + bra lz2gotof + +lz2offs9 deca ; set bits 9-15 of offset, reverse bit 8 + bra lz2lowof + +lz2done leay 1,y ; adjust pointer to first byte of decompressed data and then exit +lz2gotnb ldb #$aa ; load nibble + andb #$0f ; only keep low 4 bits + rts diff --git a/Tools/unix/lzsa/asm/6809/unlzsa2b.s b/Tools/unix/lzsa/asm/6809/unlzsa2b.s new file mode 100644 index 00000000..b538cacb --- /dev/null +++ b/Tools/unix/lzsa/asm/6809/unlzsa2b.s @@ -0,0 +1,152 @@ +; unlzsa2b.s - 6809 backward decompression routine for raw LZSA2 - 171 bytes +; compress with lzsa -f2 -r -b +; +; in: x = last byte of compressed data +; y = last byte of decompression buffer +; out: y = first byte of decompressed data +; +; Copyright (C) 2020 Emmanuel Marty +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; 3. This notice may not be removed or altered from any source distribution. + +decompress_lzsa2 + clr ed shuttle 86765 alice 46864 robotron 303895 +++! +; baseline new test harness shuttle 83925 alice 37948 robotron 269002 *** +; Pavel optimizations shuttle 82225 alice 36798 robotron 261226 +++ +; OPTIMIZE_LONG_RLE 1 shuttle 82242 alice 36787 robotron 261392 **- +; +;------ +; +;Pavel's optimization history: +; shuttle alice robotron time in 1.193 MHz timer clocks +;baseline 19109 D9A6 570F6 +;adc cl,0->adc cl,cl 19035 D9A6 56FAB +;rep movsb->shr cx,1;jnc 18FD4 D998 56F14 +;cmp bp,-2->inc bp;inc bp 18F07 D999 56EA3 +;jz;jc->jc 18D81 D973 56B2F +;add al,3->movsb x3 18B1E D777 56197 +;more lit_len_mat tables 18A83 D341 54ACC diff --git a/Tools/unix/lzsa/src/lib.h b/Tools/unix/lzsa/src/lib.h index 5556d2a9..2520b13b 100644 --- a/Tools/unix/lzsa/src/lib.h +++ b/Tools/unix/lzsa/src/lib.h @@ -63,7 +63,7 @@ typedef enum _lzsa_status_t { /* Decompression-specific status codes */ LZSA_ERROR_FORMAT, /**< Invalid input format or magic number when decompressing */ - LZSA_ERROR_DECOMPRESSION, /**< Internal decompression error */ + LZSA_ERROR_DECOMPRESSION /**< Internal decompression error */ } lzsa_status_t; /* Compression flags */ diff --git a/Tools/unix/lzsa/src/lzsa.c b/Tools/unix/lzsa/src/lzsa.c index 4cce4041..3f6e3572 100644 --- a/Tools/unix/lzsa/src/lzsa.c +++ b/Tools/unix/lzsa/src/lzsa.c @@ -31,7 +31,6 @@ */ #include -#include #include #include #ifdef _WIN32 @@ -48,7 +47,7 @@ #define OPT_RAW_BACKWARD 8 #define OPT_STATS 16 -#define TOOL_VERSION "1.2.0" +#define TOOL_VERSION "1.3.6" /*---------------------------------------------------------------------------*/ @@ -295,7 +294,7 @@ int comparestream_open(lzsa_stream_t *stream, const char *pszCompareFilename, co pCompareStream->pCompareDataBuf = NULL; pCompareStream->nCompareDataSize = 0; - pCompareStream->f = (void*)fopen(pszCompareFilename, pszMode); + pCompareStream->f = (FILE*)fopen(pszCompareFilename, pszMode); if (pCompareStream->f) { stream->obj = pCompareStream; @@ -866,11 +865,11 @@ int main(int argc, char **argv) { const char *pszInFilename = NULL; const char *pszOutFilename = NULL; const char *pszDictionaryFilename = NULL; - bool bArgsError = false; - bool bCommandDefined = false; - bool bVerifyCompression = false; - bool bMinMatchDefined = false; - bool bFormatVersionDefined = false; + int nArgsError = 0; + int nCommandDefined = 0; + int nVerifyCompression = 0; + int nMinMatchDefined = 0; + int nFormatVersionDefined = 0; char cCommand = 'z'; int nMinMatchSize = 0; unsigned int nOptions = OPT_FAVOR_RATIO; @@ -878,51 +877,51 @@ int main(int argc, char **argv) { for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d")) { - if (!bCommandDefined) { - bCommandDefined = true; + if (!nCommandDefined) { + nCommandDefined = 1; cCommand = 'd'; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-z")) { - if (!bCommandDefined) { - bCommandDefined = true; + if (!nCommandDefined) { + nCommandDefined = 1; cCommand = 'z'; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-c")) { - if (!bVerifyCompression) { - bVerifyCompression = true; + if (!nVerifyCompression) { + nVerifyCompression = 1; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-cbench")) { - if (!bCommandDefined) { - bCommandDefined = true; + if (!nCommandDefined) { + nCommandDefined = 1; cCommand = 'B'; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-dbench")) { - if (!bCommandDefined) { - bCommandDefined = true; + if (!nCommandDefined) { + nCommandDefined = 1; cCommand = 'b'; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-test")) { - if (!bCommandDefined) { - bCommandDefined = true; + if (!nCommandDefined) { + nCommandDefined = 1; cCommand = 't'; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-D")) { if (!pszDictionaryFilename && (i + 1) < argc) { @@ -930,119 +929,119 @@ int main(int argc, char **argv) { i++; } else - bArgsError = true; + nArgsError = 1; } else if (!strncmp(argv[i], "-D", 2)) { if (!pszDictionaryFilename) { pszDictionaryFilename = argv[i] + 2; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-m")) { - if (!bMinMatchDefined && (i + 1) < argc) { + if (!nMinMatchDefined && (i + 1) < argc) { char *pEnd = NULL; nMinMatchSize = (int)strtol(argv[i + 1], &pEnd, 10); if (pEnd && pEnd != argv[i + 1] && (nMinMatchSize >= 2 && nMinMatchSize <= 5)) { i++; - bMinMatchDefined = true; + nMinMatchDefined = 1; nOptions &= (~OPT_FAVOR_RATIO); } else { - bArgsError = true; + nArgsError = 1; } } else - bArgsError = true; + nArgsError = 1; } else if (!strncmp(argv[i], "-m", 2)) { - if (!bMinMatchDefined) { + if (!nMinMatchDefined) { char *pEnd = NULL; nMinMatchSize = (int)strtol(argv[i] + 2, &pEnd, 10); if (pEnd && pEnd != (argv[i]+2) && (nMinMatchSize >= 2 && nMinMatchSize <= 5)) { - bMinMatchDefined = true; + nMinMatchDefined = 1; nOptions &= (~OPT_FAVOR_RATIO); } else { - bArgsError = true; + nArgsError = 1; } } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "--prefer-ratio")) { - if (!bMinMatchDefined) { + if (!nMinMatchDefined) { nMinMatchSize = 0; - bMinMatchDefined = true; + nMinMatchDefined = 1; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "--prefer-speed")) { - if (!bMinMatchDefined) { + if (!nMinMatchDefined) { nMinMatchSize = 3; nOptions &= (~OPT_FAVOR_RATIO); - bMinMatchDefined = true; + nMinMatchDefined = 1; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-f")) { - if (!bFormatVersionDefined && (i + 1) < argc) { + if (!nFormatVersionDefined && (i + 1) < argc) { char *pEnd = NULL; nFormatVersion = (int)strtol(argv[i + 1], &pEnd, 10); if (pEnd && pEnd != argv[i + 1] && (nFormatVersion >= 1 && nFormatVersion <= 2)) { i++; - bFormatVersionDefined = true; + nFormatVersionDefined = 1; } else { - bArgsError = true; + nArgsError = 1; } } else - bArgsError = true; + nArgsError = 1; } else if (!strncmp(argv[i], "-f", 2)) { - if (!bFormatVersionDefined) { + if (!nFormatVersionDefined) { char *pEnd = NULL; nFormatVersion = (int)strtol(argv[i] + 2, &pEnd, 10); if (pEnd && pEnd != (argv[i] + 2) && (nFormatVersion >= 1 && nFormatVersion <= 2)) { - bFormatVersionDefined = true; + nFormatVersionDefined = 1; } else { - bArgsError = true; + nArgsError = 1; } } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-v")) { if ((nOptions & OPT_VERBOSE) == 0) { nOptions |= OPT_VERBOSE; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-r")) { if ((nOptions & OPT_RAW) == 0) { nOptions |= OPT_RAW; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-b")) { if ((nOptions & OPT_RAW_BACKWARD) == 0) { nOptions |= OPT_RAW_BACKWARD; } else - bArgsError = true; + nArgsError = 1; } else if (!strcmp(argv[i], "-stats")) { if ((nOptions & OPT_STATS) == 0) { nOptions |= OPT_STATS; } else - bArgsError = true; + nArgsError = 1; } else { if (!pszInFilename) @@ -1051,21 +1050,21 @@ int main(int argc, char **argv) { if (!pszOutFilename) pszOutFilename = argv[i]; else - bArgsError = true; + nArgsError = 1; } } } - if (!bArgsError && (nOptions & OPT_RAW_BACKWARD) && !(nOptions & OPT_RAW)) { + if (!nArgsError && (nOptions & OPT_RAW_BACKWARD) && !(nOptions & OPT_RAW)) { fprintf(stderr, "error: -b (compress backwards) requires -r (raw block format)\n"); return 100; } - if (!bArgsError && cCommand == 't') { + if (!nArgsError && cCommand == 't') { return do_self_test(nOptions, nMinMatchSize, nFormatVersion); } - if (bArgsError || !pszInFilename || !pszOutFilename) { + if (nArgsError || !pszInFilename || !pszOutFilename) { fprintf(stderr, "lzsa command-line tool v" TOOL_VERSION " by Emmanuel Marty and spke\n"); fprintf(stderr, "usage: %s [-c] [-d] [-v] [-r] \n", argv[0]); fprintf(stderr, " -c: check resulting stream after compressing\n"); @@ -1089,7 +1088,7 @@ int main(int argc, char **argv) { if (cCommand == 'z') { int nResult = do_compress(pszInFilename, pszOutFilename, pszDictionaryFilename, nOptions, nMinMatchSize, nFormatVersion); - if (nResult == 0 && bVerifyCompression) { + if (nResult == 0 && nVerifyCompression) { return do_compare(pszOutFilename, pszInFilename, pszDictionaryFilename, nOptions, nFormatVersion); } else { return nResult; diff --git a/Tools/unix/lzsa/src/matchfinder.c b/Tools/unix/lzsa/src/matchfinder.c index fbdc5ca3..3de2cfa6 100644 --- a/Tools/unix/lzsa/src/matchfinder.c +++ b/Tools/unix/lzsa/src/matchfinder.c @@ -66,7 +66,7 @@ int lzsa_build_suffix_array(lzsa_compressor *pCompressor, const unsigned char *p int *PLCP = (int*)pCompressor->pos_data; /* Use temporarily */ int *Phi = PLCP; int nCurLen = 0; - int i; + int i, r; /* Compute the permuted LCP first (Krkkinen method) */ Phi[intervals[0]] = -1; @@ -132,7 +132,7 @@ int lzsa_build_suffix_array(lzsa_compressor *pCompressor, const unsigned char *p intervals[0] = 0; next_interval_idx = 1; - for (int r = 1; r < nInWindowSize; r++) { + for (r = 1; r < nInWindowSize; r++) { const unsigned int next_pos = SA_and_LCP[r] & POS_MASK; const unsigned int next_lcp = SA_and_LCP[r] & LCP_MASK; const unsigned int top_lcp = *top & LCP_MASK; diff --git a/Tools/unix/lzsa/src/shrink_block_v1.c b/Tools/unix/lzsa/src/shrink_block_v1.c index c30e4a9f..32c5c385 100644 --- a/Tools/unix/lzsa/src/shrink_block_v1.c +++ b/Tools/unix/lzsa/src/shrink_block_v1.c @@ -157,66 +157,69 @@ static inline int lzsa_get_offset_cost_v1(const unsigned int nMatchOffset) { * @param nEndOffset offset to end finding matches at (typically the size of the total input window in bytes */ static void lzsa_optimize_forward_v1(lzsa_compressor *pCompressor, lzsa_match *pBestMatch, const int nStartOffset, const int nEndOffset, const int nReduce) { - lzsa_arrival *arrival = pCompressor->arrival - (nStartOffset << MATCHES_PER_ARRIVAL_SHIFT); + lzsa_arrival *arrival = pCompressor->arrival - (nStartOffset << ARRIVALS_PER_POSITION_SHIFT); const int nMinMatchSize = pCompressor->min_match_size; const int nFavorRatio = (pCompressor->flags & LZSA_FLAG_FAVOR_RATIO) ? 1 : 0; + const int nModeSwitchPenalty = nFavorRatio ? 0 : MODESWITCH_PENALTY; const int nDisableScore = nReduce ? 0 : (2 * BLOCK_SIZE); int i, j, n; if ((nEndOffset - nStartOffset) > BLOCK_SIZE) return; - memset(arrival + (nStartOffset << MATCHES_PER_ARRIVAL_SHIFT), 0, sizeof(lzsa_arrival) * ((nEndOffset - nStartOffset + 1) << MATCHES_PER_ARRIVAL_SHIFT)); + memset(arrival + (nStartOffset << ARRIVALS_PER_POSITION_SHIFT), 0, sizeof(lzsa_arrival) * ((nEndOffset - nStartOffset + 1) << ARRIVALS_PER_POSITION_SHIFT)); - arrival[nStartOffset << MATCHES_PER_ARRIVAL_SHIFT].from_slot = -1; + arrival[nStartOffset << ARRIVALS_PER_POSITION_SHIFT].from_slot = -1; for (i = nStartOffset; i != nEndOffset; i++) { + lzsa_arrival* cur_arrival = &arrival[i << ARRIVALS_PER_POSITION_SHIFT]; int m; - for (j = 0; j < NMATCHES_PER_ARRIVAL_V1 && arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].from_slot; j++) { - int nPrevCost = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].cost; + for (j = 0; j < NARRIVALS_PER_POSITION_V1 && cur_arrival[j].from_slot; j++) { + int nPrevCost = cur_arrival[j].cost; int nCodingChoiceCost = nPrevCost + 8 /* literal */; - int nScore = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].score + 1; - int nNumLiterals = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].num_literals + 1; + int nScore = cur_arrival[j].score + 1; + int nNumLiterals = cur_arrival[j].num_literals + 1; if (nNumLiterals == LITERALS_RUN_LEN_V1 || nNumLiterals == 256 || nNumLiterals == 512) { nCodingChoiceCost += 8; } - if (!nFavorRatio && nNumLiterals == 1) - nCodingChoiceCost += MODESWITCH_PENALTY; + if (nNumLiterals == 1) + nCodingChoiceCost += nModeSwitchPenalty; - for (n = 0; n < NMATCHES_PER_ARRIVAL_V1 /* we only need the literals + short match cost + long match cost cases */; n++) { - lzsa_arrival *pDestArrival = &arrival[((i + 1) << MATCHES_PER_ARRIVAL_SHIFT) + n]; + lzsa_arrival *pDestSlots = &arrival[(i + 1) << ARRIVALS_PER_POSITION_SHIFT]; + for (n = 0; n < NARRIVALS_PER_POSITION_V1 /* we only need the literals + short match cost + long match cost cases */; n++) { + lzsa_arrival *pDestArrival = &pDestSlots[n]; if (pDestArrival->from_slot == 0 || nCodingChoiceCost < pDestArrival->cost || (nCodingChoiceCost == pDestArrival->cost && nScore < (pDestArrival->score + nDisableScore))) { - memmove(&arrival[((i + 1) << MATCHES_PER_ARRIVAL_SHIFT) + n + 1], - &arrival[((i + 1) << MATCHES_PER_ARRIVAL_SHIFT) + n], - sizeof(lzsa_arrival) * (NMATCHES_PER_ARRIVAL_V1 - n - 1)); + memmove(&arrival[((i + 1) << ARRIVALS_PER_POSITION_SHIFT) + n + 1], + &arrival[((i + 1) << ARRIVALS_PER_POSITION_SHIFT) + n], + sizeof(lzsa_arrival) * (NARRIVALS_PER_POSITION_V1 - n - 1)); pDestArrival->cost = nCodingChoiceCost; pDestArrival->from_pos = i; pDestArrival->from_slot = j + 1; - pDestArrival->match_offset = 0; pDestArrival->match_len = 0; pDestArrival->num_literals = nNumLiterals; pDestArrival->score = nScore; - pDestArrival->rep_offset = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_offset; + pDestArrival->rep_offset = cur_arrival[j].rep_offset; break; } } } const lzsa_match *match = pCompressor->match + ((i - nStartOffset) << MATCHES_PER_INDEX_SHIFT_V1); + int nNumArrivalsForThisPos = j; for (m = 0; m < NMATCHES_PER_INDEX_V1 && match[m].length; m++) { int nMatchLen = match[m].length; int nMatchOffsetCost = lzsa_get_offset_cost_v1(match[m].offset); int nStartingMatchLen, k; - if ((i + nMatchLen) > (nEndOffset - LAST_LITERALS)) - nMatchLen = nEndOffset - LAST_LITERALS - i; + if ((i + nMatchLen) > nEndOffset) + nMatchLen = nEndOffset - i; if (nMatchLen >= LEAVE_ALONE_MATCH_SIZE) nStartingMatchLen = nMatchLen; @@ -225,43 +228,48 @@ static void lzsa_optimize_forward_v1(lzsa_compressor *pCompressor, lzsa_match *p for (k = nStartingMatchLen; k <= nMatchLen; k++) { int nMatchLenCost = lzsa_get_match_varlen_size_v1(k - MIN_MATCH_SIZE_V1); - for (j = 0; j < NMATCHES_PER_ARRIVAL_V1 && arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].from_slot; j++) { - int nPrevCost = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].cost; + lzsa_arrival *pDestSlots = &arrival[(i + k) << ARRIVALS_PER_POSITION_SHIFT]; + + for (j = 0; j < nNumArrivalsForThisPos; j++) { + int nPrevCost = cur_arrival[j].cost; int nCodingChoiceCost = nPrevCost + 8 /* token */ /* the actual cost of the literals themselves accumulates up the chain */ + nMatchOffsetCost + nMatchLenCost; - int nScore = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].score + 5; int exists = 0; - if (!nFavorRatio && !arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].num_literals) - nCodingChoiceCost += MODESWITCH_PENALTY; + if (!cur_arrival[j].num_literals) + nCodingChoiceCost += nModeSwitchPenalty; for (n = 0; - n < NMATCHES_PER_ARRIVAL_V1 && arrival[((i + k) << MATCHES_PER_ARRIVAL_SHIFT) + n].from_slot && arrival[((i + k) << MATCHES_PER_ARRIVAL_SHIFT) + n].cost <= nCodingChoiceCost; + n < NARRIVALS_PER_POSITION_V1 && pDestSlots[n].from_slot && pDestSlots[n].cost <= nCodingChoiceCost; n++) { - if (lzsa_get_offset_cost_v1(arrival[((i + k) << MATCHES_PER_ARRIVAL_SHIFT) + n].rep_offset) == lzsa_get_offset_cost_v1(match[m].offset)) { + if (lzsa_get_offset_cost_v1(pDestSlots[n].rep_offset) == nMatchOffsetCost) { exists = 1; break; } } - for (n = 0; !exists && n < NMATCHES_PER_ARRIVAL_V1 /* we only need the literals + short match cost + long match cost cases */; n++) { - lzsa_arrival *pDestArrival = &arrival[((i + k) << MATCHES_PER_ARRIVAL_SHIFT) + n]; - - if (pDestArrival->from_slot == 0 || - nCodingChoiceCost < pDestArrival->cost || - (nCodingChoiceCost == pDestArrival->cost && nScore < (pDestArrival->score + nDisableScore))) { - memmove(&arrival[((i + k) << MATCHES_PER_ARRIVAL_SHIFT) + n + 1], - &arrival[((i + k) << MATCHES_PER_ARRIVAL_SHIFT) + n], - sizeof(lzsa_arrival) * (NMATCHES_PER_ARRIVAL_V1 - n - 1)); - - pDestArrival->cost = nCodingChoiceCost; - pDestArrival->from_pos = i; - pDestArrival->from_slot = j + 1; - pDestArrival->match_offset = match[m].offset; - pDestArrival->match_len = k; - pDestArrival->num_literals = 0; - pDestArrival->score = nScore; - pDestArrival->rep_offset = match[m].offset; - break; + if (!exists) { + int nScore = cur_arrival[j].score + 5; + + for (n = 0; n < NARRIVALS_PER_POSITION_V1 /* we only need the literals + short match cost + long match cost cases */; n++) { + lzsa_arrival *pDestArrival = &pDestSlots[n]; + + if (pDestArrival->from_slot == 0 || + nCodingChoiceCost < pDestArrival->cost || + (nCodingChoiceCost == pDestArrival->cost && nScore < (pDestArrival->score + nDisableScore))) { + memmove(&pDestSlots[n + 1], + &pDestSlots[n], + sizeof(lzsa_arrival) * (NARRIVALS_PER_POSITION_V1 - n - 1)); + + pDestArrival->cost = nCodingChoiceCost; + pDestArrival->from_pos = i; + pDestArrival->from_slot = j + 1; + pDestArrival->match_len = k; + pDestArrival->num_literals = 0; + pDestArrival->score = nScore; + pDestArrival->rep_offset = match[m].offset; + j = NARRIVALS_PER_POSITION_V1; + break; + } } } } @@ -269,14 +277,17 @@ static void lzsa_optimize_forward_v1(lzsa_compressor *pCompressor, lzsa_match *p } } - lzsa_arrival *end_arrival = &arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + 0]; + lzsa_arrival *end_arrival = &arrival[(i << ARRIVALS_PER_POSITION_SHIFT) + 0]; while (end_arrival->from_slot > 0 && end_arrival->from_pos >= 0) { if (end_arrival->from_pos >= nEndOffset) return; pBestMatch[end_arrival->from_pos].length = end_arrival->match_len; - pBestMatch[end_arrival->from_pos].offset = end_arrival->match_offset; + if (end_arrival->match_len) + pBestMatch[end_arrival->from_pos].offset = end_arrival->rep_offset; + else + pBestMatch[end_arrival->from_pos].offset = 0; - end_arrival = &arrival[(end_arrival->from_pos << MATCHES_PER_ARRIVAL_SHIFT) + (end_arrival->from_slot - 1)]; + end_arrival = &arrival[(end_arrival->from_pos << ARRIVALS_PER_POSITION_SHIFT) + (end_arrival->from_slot - 1)]; } } @@ -301,12 +312,12 @@ static int lzsa_optimize_command_count_v1(lzsa_compressor *pCompressor, const un lzsa_match *pMatch = pBestMatch + i; if (pMatch->length == 0 && - (i + 1) < (nEndOffset - LAST_LITERALS) && + (i + 1) < nEndOffset && pBestMatch[i + 1].length >= MIN_MATCH_SIZE_V1 && pBestMatch[i + 1].length < MAX_VARLEN && pBestMatch[i + 1].offset && i >= pBestMatch[i + 1].offset && - (i + pBestMatch[i + 1].length + 1) <= (nEndOffset - LAST_LITERALS) && + (i + pBestMatch[i + 1].length + 1) <= nEndOffset && !memcmp(pInWindow + i - (pBestMatch[i + 1].offset), pInWindow + i, pBestMatch[i + 1].length + 1)) { int nCurLenSize = lzsa_get_match_varlen_size_v1(pBestMatch[i + 1].length - MIN_MATCH_SIZE_V1); int nReducedLenSize = lzsa_get_match_varlen_size_v1(pBestMatch[i + 1].length + 1 - MIN_MATCH_SIZE_V1); @@ -413,8 +424,6 @@ static int lzsa_get_compressed_size_v1(lzsa_compressor *pCompressor, lzsa_match int nMatchOffset = pMatch->offset; int nMatchLen = pMatch->length; int nEncodedMatchLen = nMatchLen - MIN_MATCH_SIZE_V1; - int nTokenLiteralsLen = (nNumLiterals >= LITERALS_RUN_LEN_V1) ? LITERALS_RUN_LEN_V1 : nNumLiterals; - int nTokenMatchLen = (nEncodedMatchLen >= MATCH_RUN_LEN_V1) ? MATCH_RUN_LEN_V1 : nEncodedMatchLen; int nTokenLongOffset = (nMatchOffset <= 256) ? 0x00 : 0x80; int nCommandSize = 8 /* token */ + lzsa_get_literals_varlen_size_v1(nNumLiterals) + (nNumLiterals << 3) + (nTokenLongOffset ? 16 : 8) /* match offset */ + lzsa_get_match_varlen_size_v1(nEncodedMatchLen); @@ -429,7 +438,6 @@ static int lzsa_get_compressed_size_v1(lzsa_compressor *pCompressor, lzsa_match } { - int nTokenLiteralsLen = (nNumLiterals >= LITERALS_RUN_LEN_V1) ? LITERALS_RUN_LEN_V1 : nNumLiterals; int nCommandSize = 8 /* token */ + lzsa_get_literals_varlen_size_v1(nNumLiterals) + (nNumLiterals << 3); nCompressedSize += nCommandSize; diff --git a/Tools/unix/lzsa/src/shrink_block_v2.c b/Tools/unix/lzsa/src/shrink_block_v2.c index eb4a16ed..fc6d2324 100644 --- a/Tools/unix/lzsa/src/shrink_block_v2.c +++ b/Tools/unix/lzsa/src/shrink_block_v2.c @@ -43,22 +43,18 @@ * @param nOutOffset current write index into output buffer * @param nMaxOutDataSize maximum size of output buffer, in bytes * @param nCurNibbleOffset write index into output buffer, of current byte being filled with nibbles - * @param nCurFreeNibbles current number of free nibbles in byte * @param nNibbleValue value to write (0..15) */ -static int lzsa_write_nibble_v2(unsigned char *pOutData, int nOutOffset, const int nMaxOutDataSize, int *nCurNibbleOffset, int *nCurFreeNibbles, int nNibbleValue) { +static int lzsa_write_nibble_v2(unsigned char *pOutData, int nOutOffset, const int nMaxOutDataSize, int *nCurNibbleOffset, int nNibbleValue) { if (nOutOffset < 0) return -1; if ((*nCurNibbleOffset) == -1) { if (nOutOffset >= nMaxOutDataSize) return -1; (*nCurNibbleOffset) = nOutOffset; - (*nCurFreeNibbles) = 2; - pOutData[nOutOffset++] = 0; + pOutData[nOutOffset++] = nNibbleValue << 4; } - - pOutData[*nCurNibbleOffset] = (pOutData[*nCurNibbleOffset] << 4) | (nNibbleValue & 0x0f); - (*nCurFreeNibbles)--; - if ((*nCurFreeNibbles) == 0) { + else { + pOutData[*nCurNibbleOffset] = (pOutData[*nCurNibbleOffset]) | (nNibbleValue & 0x0f); (*nCurNibbleOffset) = -1; } @@ -96,15 +92,17 @@ static inline int lzsa_get_literals_varlen_size_v2(const int nLength) { * * @param pOutData pointer to output buffer * @param nOutOffset current write index into output buffer + * @param nMaxOutDataSize maximum size of output buffer, in bytes + * @param nCurNibbleOffset write index into output buffer, of current byte being filled with nibbles * @param nLength literals length */ -static inline int lzsa_write_literals_varlen_v2(unsigned char *pOutData, int nOutOffset, const int nMaxOutDataSize, int *nCurNibbleOffset, int *nCurFreeNibbles, int nLength) { +static inline int lzsa_write_literals_varlen_v2(unsigned char *pOutData, int nOutOffset, const int nMaxOutDataSize, int *nCurNibbleOffset, int nLength) { if (nLength >= LITERALS_RUN_LEN_V2) { if (nLength < (LITERALS_RUN_LEN_V2 + 15)) { - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, nCurNibbleOffset, nCurFreeNibbles, nLength - LITERALS_RUN_LEN_V2); + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, nCurNibbleOffset, nLength - LITERALS_RUN_LEN_V2); } else { - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, nCurNibbleOffset, nCurFreeNibbles, 15); + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, nCurNibbleOffset, 15); if (nOutOffset < 0) return -1; if (nLength < 256) @@ -150,15 +148,17 @@ static inline int lzsa_get_match_varlen_size_v2(const int nLength) { * * @param pOutData pointer to output buffer * @param nOutOffset current write index into output buffer + * @param nMaxOutDataSize maximum size of output buffer, in bytes + * @param nCurNibbleOffset write index into output buffer, of current byte being filled with nibbles * @param nLength encoded match length (actual match length - MIN_MATCH_SIZE_V2) */ -static inline int lzsa_write_match_varlen_v2(unsigned char *pOutData, int nOutOffset, const int nMaxOutDataSize, int *nCurNibbleOffset, int *nCurFreeNibbles, int nLength) { +static inline int lzsa_write_match_varlen_v2(unsigned char *pOutData, int nOutOffset, const int nMaxOutDataSize, int *nCurNibbleOffset, int nLength) { if (nLength >= MATCH_RUN_LEN_V2) { if (nLength < (MATCH_RUN_LEN_V2 + 15)) { - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, nCurNibbleOffset, nCurFreeNibbles, nLength - MATCH_RUN_LEN_V2); + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, nCurNibbleOffset, nLength - MATCH_RUN_LEN_V2); } else { - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, nCurNibbleOffset, nCurFreeNibbles, 15); + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, nCurNibbleOffset, 15); if (nOutOffset < 0) return -1; if ((nLength + MIN_MATCH_SIZE_V2) < 256) @@ -183,58 +183,72 @@ static inline int lzsa_write_match_varlen_v2(unsigned char *pOutData, int nOutOf * @param nMatchOffset match offset to use as rep candidate * @param nStartOffset current offset in input window (typically the number of previously compressed bytes) * @param nEndOffset offset to end finding matches at (typically the size of the total input window in bytes - * @param nMatchesPerArrival number of arrivals to record per input buffer position * @param nDepth current insertion depth */ -static void lzsa_insert_forward_match_v2(lzsa_compressor *pCompressor, const unsigned char *pInWindow, const int i, const int nMatchOffset, const int nStartOffset, const int nEndOffset, const int nMatchesPerArrival, int nDepth) { - lzsa_arrival *arrival = pCompressor->arrival - (nStartOffset << MATCHES_PER_ARRIVAL_SHIFT); +static void lzsa_insert_forward_match_v2(lzsa_compressor *pCompressor, const unsigned char *pInWindow, const int i, const int nMatchOffset, const int nStartOffset, const int nEndOffset, int nDepth) { + lzsa_arrival *arrival = pCompressor->arrival + ((i - nStartOffset) << ARRIVALS_PER_POSITION_SHIFT); + const int *rle_len = (int*)pCompressor->intervals /* reuse */; + lzsa_match* visited = ((lzsa_match*)pCompressor->pos_data) - nStartOffset /* reuse */; int j; - if (nDepth >= 10) return; + for (j = 0; j < NARRIVALS_PER_POSITION_V2_BIG && arrival[j].from_slot; j++) { + int nRepOffset = arrival[j].rep_offset; - for (j = 0; j < nMatchesPerArrival && arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].from_slot; j++) { - int nRepOffset = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_offset; - - if (nMatchOffset != nRepOffset && nRepOffset && arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_len >= MIN_MATCH_SIZE_V2) { - int nRepPos = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_pos; - int nRepLen = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_len; + if (nMatchOffset != nRepOffset && nRepOffset && arrival[j].rep_len >= MIN_MATCH_SIZE_V2) { + int nRepPos = arrival[j].rep_pos; + int nRepLen = arrival[j].rep_len; if (nRepPos > nMatchOffset && - (nRepPos - nMatchOffset + nRepLen) <= (nEndOffset - LAST_LITERALS) && - !memcmp(pInWindow + nRepPos - nRepOffset, pInWindow + nRepPos - nMatchOffset, nRepLen)) { - int nCurRepLen = nRepLen; - - int nMaxRepLen = nEndOffset - nRepPos; - if (nMaxRepLen > LCP_MAX) - nMaxRepLen = LCP_MAX; - while ((nCurRepLen + 8) < nMaxRepLen && !memcmp(pInWindow + nRepPos + nCurRepLen, pInWindow + nRepPos - nMatchOffset + nCurRepLen, 8)) - nCurRepLen += 8; - while ((nCurRepLen + 4) < nMaxRepLen && !memcmp(pInWindow + nRepPos + nCurRepLen, pInWindow + nRepPos - nMatchOffset + nCurRepLen, 4)) - nCurRepLen += 4; - while (nCurRepLen < nMaxRepLen && pInWindow[nRepPos + nCurRepLen] == pInWindow[nRepPos - nMatchOffset + nCurRepLen]) - nCurRepLen++; - - lzsa_match *fwd_match = pCompressor->match + ((nRepPos - nStartOffset) << MATCHES_PER_INDEX_SHIFT_V2); - int exists = 0; - int r; + (nRepPos + nRepLen) <= nEndOffset && + pCompressor->match[((nRepPos - nStartOffset) << MATCHES_PER_INDEX_SHIFT_V2) + NMATCHES_PER_INDEX_V2 - 1].length == 0) { - for (r = 0; r < NMATCHES_PER_INDEX_V2 && fwd_match[r].length >= MIN_MATCH_SIZE_V2; r++) { - if (fwd_match[r].offset == nMatchOffset) { - exists = 1; + if (visited[nRepPos].offset != nMatchOffset || visited[nRepPos].length > nRepLen) { + visited[nRepPos].offset = nMatchOffset; + visited[nRepPos].length = nRepLen; - if (fwd_match[r].length < nCurRepLen) { - fwd_match[r].length = nCurRepLen; - lzsa_insert_forward_match_v2(pCompressor, pInWindow, nRepPos, nMatchOffset, nStartOffset, nEndOffset, nMatchesPerArrival, nDepth + 1); - } - break; - } - } + if (pInWindow[nRepPos] == pInWindow[nRepPos - nMatchOffset]) { + int nLen0 = rle_len[nRepPos - nMatchOffset]; + int nLen1 = rle_len[nRepPos]; + int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1; + + if (nMinLen >= nRepLen || !memcmp(pInWindow + nRepPos + nMinLen, pInWindow + nRepPos + nMinLen - nMatchOffset, nRepLen - nMinLen)) { + visited[nRepPos].length = 0; - if (!exists && r < NMATCHES_PER_INDEX_V2) { - fwd_match[r].offset = nMatchOffset; - fwd_match[r].length = nCurRepLen; + lzsa_match* fwd_match = pCompressor->match + ((nRepPos - nStartOffset) << MATCHES_PER_INDEX_SHIFT_V2); + int r; + + for (r = 0; r < NMATCHES_PER_INDEX_V2 && fwd_match[r].length >= MIN_MATCH_SIZE_V2; r++) { + if (fwd_match[r].offset == nMatchOffset) { + r = NMATCHES_PER_INDEX_V2; + break; + } + } - lzsa_insert_forward_match_v2(pCompressor, pInWindow, nRepPos, nMatchOffset, nStartOffset, nEndOffset, nMatchesPerArrival, nDepth + 1); + if (r < NMATCHES_PER_INDEX_V2) { + int nMaxRepLen = nEndOffset - nRepPos; + if (nMaxRepLen > LCP_MAX) + nMaxRepLen = LCP_MAX; + int nCurRepLen = (nMinLen > nRepLen) ? nMinLen : nRepLen; + if (nCurRepLen > nMaxRepLen) + nCurRepLen = nMaxRepLen; + const unsigned char* pInWindowMax = pInWindow + nRepPos + nMaxRepLen; + const unsigned char* pInWindowAtRepPos = pInWindow + nRepPos + nCurRepLen; + while ((pInWindowAtRepPos + 8) < pInWindowMax && !memcmp(pInWindowAtRepPos, pInWindowAtRepPos - nMatchOffset, 8)) + pInWindowAtRepPos += 8; + while ((pInWindowAtRepPos + 4) < pInWindowMax && !memcmp(pInWindowAtRepPos, pInWindowAtRepPos - nMatchOffset, 4)) + pInWindowAtRepPos += 4; + while (pInWindowAtRepPos < pInWindowMax && pInWindowAtRepPos[0] == pInWindowAtRepPos[-nMatchOffset]) + pInWindowAtRepPos++; + + nCurRepLen = (int)(pInWindowAtRepPos - (pInWindow + nRepPos)); + fwd_match[r].offset = nMatchOffset; + fwd_match[r].length = nCurRepLen; + + if (nDepth < 9) + lzsa_insert_forward_match_v2(pCompressor, pInWindow, nRepPos, nMatchOffset, nStartOffset, nEndOffset, nDepth + 1); + } + } + } } } } @@ -251,33 +265,44 @@ static void lzsa_insert_forward_match_v2(lzsa_compressor *pCompressor, const uns * @param nEndOffset offset to end finding matches at (typically the size of the total input window in bytes * @param nReduce non-zero to reduce the number of tokens when the path costs are equal, zero not to * @param nInsertForwardReps non-zero to insert forward repmatch candidates, zero to use the previously inserted candidates - * @param nMatchesPerArrival number of arrivals to record per input buffer position + * @param nArrivalsPerPosition number of arrivals to record per input buffer position */ -static void lzsa_optimize_forward_v2(lzsa_compressor *pCompressor, const unsigned char *pInWindow, lzsa_match *pBestMatch, const int nStartOffset, const int nEndOffset, const int nReduce, const int nInsertForwardReps, const int nMatchesPerArrival) { - lzsa_arrival *arrival = pCompressor->arrival - (nStartOffset << MATCHES_PER_ARRIVAL_SHIFT); - const int nFavorRatio = (pCompressor->flags & LZSA_FLAG_FAVOR_RATIO) ? 1 : 0; +static void lzsa_optimize_forward_v2(lzsa_compressor *pCompressor, const unsigned char *pInWindow, lzsa_match *pBestMatch, const int nStartOffset, const int nEndOffset, const int nReduce, const int nInsertForwardReps, const int nArrivalsPerPosition) { + lzsa_arrival *arrival = pCompressor->arrival - (nStartOffset << ARRIVALS_PER_POSITION_SHIFT); + const int *rle_len = (int*)pCompressor->intervals /* reuse */; + lzsa_match *visited = ((lzsa_match*)pCompressor->pos_data) - nStartOffset /* reuse */; + char *nRepSlotHandledMask = pCompressor->rep_slot_handled_mask; + char *nRepLenHandledMask = pCompressor->rep_len_handled_mask; + const int nModeSwitchPenalty = (pCompressor->flags & LZSA_FLAG_FAVOR_RATIO) ? 0 : MODESWITCH_PENALTY; const int nMinMatchSize = pCompressor->min_match_size; const int nDisableScore = nReduce ? 0 : (2 * BLOCK_SIZE); - const int nLeaveAloneMatchSize = (nMatchesPerArrival == NMATCHES_PER_ARRIVAL_V2_SMALL) ? LEAVE_ALONE_MATCH_SIZE_SMALL : LEAVE_ALONE_MATCH_SIZE; + const int nMaxRepInsertedLen = nReduce ? LEAVE_ALONE_MATCH_SIZE : 0; + const int nLeaveAloneMatchSize = (nArrivalsPerPosition == NARRIVALS_PER_POSITION_V2_SMALL) ? LEAVE_ALONE_MATCH_SIZE_SMALL : LEAVE_ALONE_MATCH_SIZE; int i, j, n; if ((nEndOffset - nStartOffset) > BLOCK_SIZE) return; - memset(arrival + (nStartOffset << MATCHES_PER_ARRIVAL_SHIFT), 0, sizeof(lzsa_arrival) * ((nEndOffset - nStartOffset + 1) << MATCHES_PER_ARRIVAL_SHIFT)); + memset(arrival + (nStartOffset << ARRIVALS_PER_POSITION_SHIFT), 0, sizeof(lzsa_arrival) * ((nEndOffset - nStartOffset + 1) << ARRIVALS_PER_POSITION_SHIFT)); - for (i = (nStartOffset << MATCHES_PER_ARRIVAL_SHIFT); i != ((nEndOffset + 1) << MATCHES_PER_ARRIVAL_SHIFT); i++) { + for (i = (nStartOffset << ARRIVALS_PER_POSITION_SHIFT); i != ((nEndOffset + 1) << ARRIVALS_PER_POSITION_SHIFT); i++) { arrival[i].cost = 0x40000000; } - arrival[nStartOffset << MATCHES_PER_ARRIVAL_SHIFT].from_slot = -1; + arrival[nStartOffset << ARRIVALS_PER_POSITION_SHIFT].from_slot = -1; + + if (nInsertForwardReps) { + memset(visited + nStartOffset, 0, (nEndOffset - nStartOffset) * sizeof(lzsa_match)); + } for (i = nStartOffset; i != nEndOffset; i++) { + lzsa_arrival *cur_arrival = &arrival[i << ARRIVALS_PER_POSITION_SHIFT]; int m; - for (j = 0; j < nMatchesPerArrival && arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].from_slot; j++) { - const int nPrevCost = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].cost & 0x3fffffff; + for (j = 0; j < nArrivalsPerPosition && cur_arrival[j].from_slot; j++) { + const int nPrevCost = cur_arrival[j].cost & 0x3fffffff; int nCodingChoiceCost = nPrevCost + 8 /* literal */; - int nNumLiterals = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].num_literals + 1; + int nScore = cur_arrival[j].score + 1; + int nNumLiterals = cur_arrival[j].num_literals + 1; if (nNumLiterals == LITERALS_RUN_LEN_V2) { nCodingChoiceCost += 4; @@ -289,52 +314,70 @@ static void lzsa_optimize_forward_v2(lzsa_compressor *pCompressor, const unsigne nCodingChoiceCost += 16; } - if (!nFavorRatio && nNumLiterals == 1) - nCodingChoiceCost += MODESWITCH_PENALTY; + if (nNumLiterals == 1) + nCodingChoiceCost += nModeSwitchPenalty; - lzsa_arrival *pDestSlots = &arrival[(i + 1) << MATCHES_PER_ARRIVAL_SHIFT]; - if (nCodingChoiceCost <= pDestSlots[nMatchesPerArrival - 1].cost) { + lzsa_arrival *pDestSlots = &cur_arrival[1 << ARRIVALS_PER_POSITION_SHIFT]; + if (nCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 1].cost || + (nCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 1].cost && nScore < (pDestSlots[nArrivalsPerPosition - 1].score + nDisableScore))) { + int nRepOffset = cur_arrival[j].rep_offset; int exists = 0; + for (n = 0; - n < nMatchesPerArrival && pDestSlots[n].cost <= nCodingChoiceCost; + n < nArrivalsPerPosition && pDestSlots[n].cost < nCodingChoiceCost; n++) { - if (pDestSlots[n].rep_offset == arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_offset) { + if (pDestSlots[n].rep_offset == nRepOffset) { exists = 1; break; } } if (!exists) { - int nScore = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].score + 1; - for (n = 0; n < nMatchesPerArrival; n++) { - lzsa_arrival *pDestArrival = &pDestSlots[n]; - if (nCodingChoiceCost < pDestArrival->cost || - (nCodingChoiceCost == pDestArrival->cost && nScore < (pDestArrival->score + nDisableScore))) { + for (; + n < nArrivalsPerPosition && pDestSlots[n].cost == nCodingChoiceCost && nScore >= (pDestSlots[n].score + nDisableScore); + n++) { + if (pDestSlots[n].rep_offset == nRepOffset) { + exists = 1; + break; + } + } + + if (!exists) { + if (n < nArrivalsPerPosition) { + int nn; + + for (nn = n; + nn < nArrivalsPerPosition && pDestSlots[nn].cost == nCodingChoiceCost; + nn++) { + if (pDestSlots[nn].rep_offset == nRepOffset) { + exists = 1; + break; + } + } - if (pDestArrival->from_slot) { + if (!exists) { int z; - for (z = n; z < nMatchesPerArrival - 1; z++) { - if (pDestSlots[z].rep_offset == arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_offset) + for (z = n; z < nArrivalsPerPosition - 1 && pDestSlots[z].from_slot; z++) { + if (pDestSlots[z].rep_offset == nRepOffset) break; } memmove(&pDestSlots[n + 1], &pDestSlots[n], sizeof(lzsa_arrival) * (z - n)); - } - pDestArrival->cost = nCodingChoiceCost; - pDestArrival->from_pos = i; - pDestArrival->from_slot = j + 1; - pDestArrival->match_offset = 0; - pDestArrival->match_len = 0; - pDestArrival->num_literals = nNumLiterals; - pDestArrival->score = nScore; - pDestArrival->rep_offset = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_offset; - pDestArrival->rep_pos = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_pos; - pDestArrival->rep_len = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_len; - break; + lzsa_arrival* pDestArrival = &pDestSlots[n]; + pDestArrival->cost = nCodingChoiceCost; + pDestArrival->from_pos = i; + pDestArrival->from_slot = j + 1; + pDestArrival->match_len = 0; + pDestArrival->num_literals = nNumLiterals; + pDestArrival->score = nScore; + pDestArrival->rep_offset = nRepOffset; + pDestArrival->rep_pos = cur_arrival[j].rep_pos; + pDestArrival->rep_len = cur_arrival[j].rep_len; + } } } } @@ -342,203 +385,276 @@ static void lzsa_optimize_forward_v2(lzsa_compressor *pCompressor, const unsigne } lzsa_match *match = pCompressor->match + ((i - nStartOffset) << MATCHES_PER_INDEX_SHIFT_V2); + int nNumArrivalsForThisPos = j, nMinOverallRepLen = 0, nMaxOverallRepLen = 0; + + int nRepMatchArrivalIdxAndLen[(NARRIVALS_PER_POSITION_V2_BIG * 2) + 1]; + int nNumRepMatchArrivals = 0; + + int nMaxRepLenForPos = nEndOffset - i; + if (nMaxRepLenForPos > LCP_MAX) + nMaxRepLenForPos = LCP_MAX; + const unsigned char* pInWindowStart = pInWindow + i; + const unsigned char* pInWindowMax = pInWindowStart + nMaxRepLenForPos; + + for (j = 0; j < nNumArrivalsForThisPos && (i + MIN_MATCH_SIZE_V2) <= nEndOffset; j++) { + int nRepOffset = cur_arrival[j].rep_offset; + + if (nRepOffset) { + if (i > nRepOffset) { + if (pInWindow[i] == pInWindow[i - nRepOffset]) { + const unsigned char* pInWindowAtPos; + + int nLen0 = rle_len[i - nRepOffset]; + int nLen1 = rle_len[i]; + int nMinLen = (nLen0 < nLen1) ? nLen0 : nLen1; + + if (nMinLen > nMaxRepLenForPos) + nMinLen = nMaxRepLenForPos; + pInWindowAtPos = pInWindowStart + nMinLen; + + while ((pInWindowAtPos + 8) < pInWindowMax && !memcmp(pInWindowAtPos - nRepOffset, pInWindowAtPos, 8)) + pInWindowAtPos += 8; + while ((pInWindowAtPos + 4) < pInWindowMax && !memcmp(pInWindowAtPos - nRepOffset, pInWindowAtPos, 4)) + pInWindowAtPos += 4; + while (pInWindowAtPos < pInWindowMax && pInWindowAtPos[-nRepOffset] == pInWindowAtPos[0]) + pInWindowAtPos++; + int nCurRepLen = (int)(pInWindowAtPos - pInWindowStart); + + if (nCurRepLen >= MIN_MATCH_SIZE_V2) { + if (nMaxOverallRepLen < nCurRepLen) + nMaxOverallRepLen = nCurRepLen; + nRepMatchArrivalIdxAndLen[nNumRepMatchArrivals++] = j; + nRepMatchArrivalIdxAndLen[nNumRepMatchArrivals++] = nCurRepLen; + } + } + } + } + } + nRepMatchArrivalIdxAndLen[nNumRepMatchArrivals] = -1; - int nMinRepLen[NMATCHES_PER_ARRIVAL_V2_BIG]; - memset(nMinRepLen, 0, nMatchesPerArrival * sizeof(int)); + if (!nReduce) { + memset(nRepSlotHandledMask, 0, nArrivalsPerPosition * ((LCP_MAX + 1) / 8) * sizeof(char)); + } + memset(nRepLenHandledMask, 0, ((LCP_MAX + 1) / 8) * sizeof(char)); for (m = 0; m < NMATCHES_PER_INDEX_V2 && match[m].length; m++) { int nMatchLen = match[m].length & 0x7fff; int nMatchOffset = match[m].offset; - int nScorePenalty = ((match[m].length & 0x8000) >> 15); + int nScorePenalty = 3 + ((match[m].length & 0x8000) >> 15); int nNoRepmatchOffsetCost = (nMatchOffset <= 32) ? 4 : ((nMatchOffset <= 512) ? 8 : ((nMatchOffset <= (8192 + 512)) ? 12 : 16)); int nStartingMatchLen, k; - int nMaxRepLen[NMATCHES_PER_ARRIVAL_V2_BIG]; - if ((i + nMatchLen) > (nEndOffset - LAST_LITERALS)) - nMatchLen = nEndOffset - LAST_LITERALS - i; + if ((i + nMatchLen) > nEndOffset) + nMatchLen = nEndOffset - i; - for (j = 0; j < nMatchesPerArrival && arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].from_slot; j++) { - int nRepOffset = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_offset; - int nCurMaxRepLen = 0; + if (nInsertForwardReps) + lzsa_insert_forward_match_v2(pCompressor, pInWindow, i, nMatchOffset, nStartOffset, nEndOffset, 0); - if (nRepOffset) { - if (nMatchOffset == nRepOffset) - nCurMaxRepLen = nMatchLen; - else { - if (i > nRepOffset && - (i - nRepOffset + nMatchLen) <= (nEndOffset - LAST_LITERALS)) { - nCurMaxRepLen = nMinRepLen[j]; - while ((nCurMaxRepLen + 8) < nMatchLen && !memcmp(pInWindow + i - nRepOffset + nCurMaxRepLen, pInWindow + i + nCurMaxRepLen, 8)) - nCurMaxRepLen += 8; - while ((nCurMaxRepLen + 4) < nMatchLen && !memcmp(pInWindow + i - nRepOffset + nCurMaxRepLen, pInWindow + i + nCurMaxRepLen, 4)) - nCurMaxRepLen += 4; - while (nCurMaxRepLen < nMatchLen && pInWindow[i - nRepOffset + nCurMaxRepLen] == pInWindow[i + nCurMaxRepLen]) - nCurMaxRepLen++; - nMinRepLen[j] = nCurMaxRepLen; - } - } - } + int nNonRepMatchArrivalIdx = -1; + for (j = 0; j < nNumArrivalsForThisPos; j++) { + int nRepOffset = cur_arrival[j].rep_offset; - nMaxRepLen[j] = nCurMaxRepLen; + if (nMatchOffset != nRepOffset) { + nNonRepMatchArrivalIdx = j; + break; + } } - while (j < nMatchesPerArrival) - nMaxRepLen[j++] = 0; - if (nInsertForwardReps) - lzsa_insert_forward_match_v2(pCompressor, pInWindow, i, nMatchOffset, nStartOffset, nEndOffset, nMatchesPerArrival, 0); - - int nMatchLenCost = 0; + int nMatchLenCost; if (nMatchLen >= nLeaveAloneMatchSize) { nStartingMatchLen = nMatchLen; - nMatchLenCost = 4 + 24; + nMatchLenCost = 4 + 24 + 8 /* token */; } else { nStartingMatchLen = nMinMatchSize; - nMatchLenCost = 0; + nMatchLenCost = 0 + 8 /* token */; } for (k = nStartingMatchLen; k <= nMatchLen; k++) { if (k == (MATCH_RUN_LEN_V2 + MIN_MATCH_SIZE_V2)) { - nMatchLenCost = 4; + nMatchLenCost = 4 + 8 /* token */; } else { if (k == (MATCH_RUN_LEN_V2 + 15 + MIN_MATCH_SIZE_V2)) - nMatchLenCost = 4 + 8; + nMatchLenCost = 4 + 8 + 8 /* token */; else { if (k == 256) - nMatchLenCost = 4 + 24; + nMatchLenCost = 4 + 24 + 8 /* token */; } } - lzsa_arrival *pDestSlots = &arrival[(i + k) << MATCHES_PER_ARRIVAL_SHIFT]; - int nInsertedNoRepMatchCandidate = 0; + lzsa_arrival *pDestSlots = &cur_arrival[k << ARRIVALS_PER_POSITION_SHIFT]; - for (j = 0; j < nMatchesPerArrival && arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].from_slot; j++) { - const int nPrevCost = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].cost & 0x3fffffff; - int nRepCodingChoiceCost = nPrevCost + 8 /* token */ /* the actual cost of the literals themselves accumulates up the chain */ + nMatchLenCost; + /* Insert non-repmatch candidate */ - if (nRepCodingChoiceCost <= pDestSlots[nMatchesPerArrival - 1].cost) { - int nRepOffset = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].rep_offset; + if (nNonRepMatchArrivalIdx >= 0) { + const int nPrevCost = cur_arrival[nNonRepMatchArrivalIdx].cost & 0x3fffffff; + int nCodingChoiceCost = nPrevCost /* the actual cost of the literals themselves accumulates up the chain */ + nMatchLenCost + nNoRepmatchOffsetCost; - if (nMatchOffset != nRepOffset && !nInsertedNoRepMatchCandidate) { - int nCodingChoiceCost = nRepCodingChoiceCost + nNoRepmatchOffsetCost; + if (!cur_arrival[nNonRepMatchArrivalIdx].num_literals) + nCodingChoiceCost += nModeSwitchPenalty; - if (!nFavorRatio && !arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].num_literals) - nCodingChoiceCost += MODESWITCH_PENALTY; + int nScore = cur_arrival[nNonRepMatchArrivalIdx].score + nScorePenalty; + if (nCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 2].cost || + (nCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 2].cost && nScore < (pDestSlots[nArrivalsPerPosition - 2].score + nDisableScore))) { + int exists = 0; - if (nCodingChoiceCost <= pDestSlots[nMatchesPerArrival - 1].cost) { - int exists = 0; - int nScore = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].score + 3 + nScorePenalty; + for (n = 0; + n < nArrivalsPerPosition && pDestSlots[n].cost < nCodingChoiceCost; + n++) { + if (pDestSlots[n].rep_offset == nMatchOffset) { + exists = 1; + break; + } + } - for (n = 0; - n < nMatchesPerArrival && pDestSlots[n].cost <= nCodingChoiceCost; - n++) { - if (pDestSlots[n].rep_offset == nMatchOffset && - (!nInsertForwardReps || pDestSlots[n].cost != nCodingChoiceCost || pDestSlots[n].rep_pos >= i || nScore >= (pDestSlots[n].score + nDisableScore) || - pDestSlots[nMatchesPerArrival - 1].from_slot)) { - exists = 1; - break; - } + if (!exists) { + for (; + n < nArrivalsPerPosition && pDestSlots[n].cost == nCodingChoiceCost && nScore >= (pDestSlots[n].score + nDisableScore); + n++) { + if (pDestSlots[n].rep_offset == nMatchOffset) { + exists = 1; + break; } + } - if (!exists) { - for (n = 0; n < nMatchesPerArrival - 1; n++) { - lzsa_arrival *pDestArrival = &pDestSlots[n]; + if (!exists) { + if (n < nArrivalsPerPosition - 1) { + int nn; + + for (nn = n; + nn < nArrivalsPerPosition && pDestSlots[nn].cost == nCodingChoiceCost; + nn++) { + if (pDestSlots[nn].rep_offset == nMatchOffset && + (!nInsertForwardReps || pDestSlots[nn].rep_pos >= i || + pDestSlots[nArrivalsPerPosition - 1].from_slot)) { + exists = 1; + break; + } + } - if (nCodingChoiceCost < pDestArrival->cost || - (nCodingChoiceCost == pDestArrival->cost && nScore < (pDestArrival->score + nDisableScore))) { - if (pDestArrival->from_slot) { - int z; + if (!exists) { + int z; - for (z = n; z < nMatchesPerArrival - 1; z++) { - if (pDestSlots[z].rep_offset == nMatchOffset) - break; - } + for (z = n; z < nArrivalsPerPosition - 1 && pDestSlots[z].from_slot; z++) { + if (pDestSlots[z].rep_offset == nMatchOffset) + break; + } - if (z == (nMatchesPerArrival - 1) && pDestSlots[z].from_slot && pDestSlots[z].match_len < MIN_MATCH_SIZE_V2) - z--; + if (z == (nArrivalsPerPosition - 1) && pDestSlots[z].from_slot && pDestSlots[z].match_len < MIN_MATCH_SIZE_V2) + z--; - memmove(&pDestSlots[n + 1], - &pDestSlots[n], - sizeof(lzsa_arrival) * (z - n)); - } + memmove(&pDestSlots[n + 1], + &pDestSlots[n], + sizeof(lzsa_arrival) * (z - n)); - pDestArrival->cost = nCodingChoiceCost; - pDestArrival->from_pos = i; - pDestArrival->from_slot = j + 1; - pDestArrival->match_offset = nMatchOffset; - pDestArrival->match_len = k; - pDestArrival->num_literals = 0; - pDestArrival->score = nScore; - pDestArrival->rep_offset = nMatchOffset; - pDestArrival->rep_pos = i; - pDestArrival->rep_len = k; - nInsertedNoRepMatchCandidate = 1; - break; - } + lzsa_arrival* pDestArrival = &pDestSlots[n]; + pDestArrival->cost = nCodingChoiceCost; + pDestArrival->from_pos = i; + pDestArrival->from_slot = nNonRepMatchArrivalIdx + 1; + pDestArrival->match_len = k; + pDestArrival->num_literals = 0; + pDestArrival->score = nScore; + pDestArrival->rep_offset = nMatchOffset; + pDestArrival->rep_pos = i; + pDestArrival->rep_len = k; + nRepLenHandledMask[k >> 3] &= ~(1 << (k & 7)); } } } } + } + } - /* If this coding choice doesn't rep-match, see if we still get a match by using the current repmatch offset for this arrival. This can occur (and not have the - * matchfinder offer the offset in the first place, or have too many choices with the same cost to retain the repmatchable offset) when compressing regions - * of identical bytes, for instance. Checking for this provides a big compression win on some files. */ + /* Insert repmatch candidates */ - if (nMaxRepLen[j] >= k) { - int exists = 0; + if (k > nMinOverallRepLen && k <= nMaxOverallRepLen && (nRepLenHandledMask[k >> 3] & (1 << (k & 7))) == 0) { + int nCurRepMatchArrival; - /* A match is possible at the rep offset; insert the extra coding choice. */ + nRepLenHandledMask[k >> 3] |= 1 << (k & 7); - for (n = 0; - n < nMatchesPerArrival && pDestSlots[n].cost <= nRepCodingChoiceCost; - n++) { - if (pDestSlots[n].rep_offset == nRepOffset) { - exists = 1; - break; - } - } + for (nCurRepMatchArrival = 0; (j = nRepMatchArrivalIdxAndLen[nCurRepMatchArrival]) >= 0; nCurRepMatchArrival += 2) { + int nMaskOffset = (j << 7) + (k >> 3); + if (nRepMatchArrivalIdxAndLen[nCurRepMatchArrival + 1] >= k && (nReduce || !(nRepSlotHandledMask[nMaskOffset] & (1 << (k & 7))))) { + const int nPrevCost = cur_arrival[j].cost & 0x3fffffff; + int nRepCodingChoiceCost = nPrevCost /* the actual cost of the literals themselves accumulates up the chain */ + nMatchLenCost; + int nScore = cur_arrival[j].score + 2; - if (!exists) { - int nScore = arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + j].score + 2; + if (nRepCodingChoiceCost < pDestSlots[nArrivalsPerPosition - 1].cost || + (nRepCodingChoiceCost == pDestSlots[nArrivalsPerPosition - 1].cost && nScore < (pDestSlots[nArrivalsPerPosition - 1].score + nDisableScore))) { + int nRepOffset = cur_arrival[j].rep_offset; + int exists = 0; - for (n = 0; n < nMatchesPerArrival; n++) { - lzsa_arrival *pDestArrival = &pDestSlots[n]; + for (n = 0; + n < nArrivalsPerPosition && pDestSlots[n].cost < nRepCodingChoiceCost; + n++) { + if (pDestSlots[n].rep_offset == nRepOffset) { + exists = 1; + if (!nReduce) + nRepSlotHandledMask[nMaskOffset] |= 1 << (k & 7); + break; + } + } - if (nRepCodingChoiceCost < pDestArrival->cost || - (nRepCodingChoiceCost == pDestArrival->cost && nScore < (pDestArrival->score + nDisableScore))) { - if (pDestArrival->from_slot) { - int z; + if (!exists) { + for (; + n < nArrivalsPerPosition && pDestSlots[n].cost == nRepCodingChoiceCost && nScore >= (pDestSlots[n].score + nDisableScore); + n++) { + if (pDestSlots[n].rep_offset == nRepOffset) { + exists = 1; + break; + } + } - for (z = n; z < nMatchesPerArrival - 1; z++) { - if (pDestSlots[z].rep_offset == nRepOffset) + if (!exists) { + if (n < nArrivalsPerPosition) { + int nn; + + for (nn = n; + nn < nArrivalsPerPosition && pDestSlots[nn].cost == nRepCodingChoiceCost; + nn++) { + if (pDestSlots[nn].rep_offset == nRepOffset) { + exists = 1; break; + } } - memmove(&pDestSlots[n + 1], - &pDestSlots[n], - sizeof(lzsa_arrival) * (z - n)); - } + if (!exists) { + int z; - pDestArrival->cost = nRepCodingChoiceCost; - pDestArrival->from_pos = i; - pDestArrival->from_slot = j + 1; - pDestArrival->match_offset = nRepOffset; - pDestArrival->match_len = k; - pDestArrival->num_literals = 0; - pDestArrival->score = nScore; - pDestArrival->rep_offset = nRepOffset; - pDestArrival->rep_pos = i; - pDestArrival->rep_len = k; - break; + for (z = n; z < nArrivalsPerPosition - 1 && pDestSlots[z].from_slot; z++) { + if (pDestSlots[z].rep_offset == nRepOffset) + break; + } + + memmove(&pDestSlots[n + 1], + &pDestSlots[n], + sizeof(lzsa_arrival) * (z - n)); + + lzsa_arrival* pDestArrival = &pDestSlots[n]; + pDestArrival->cost = nRepCodingChoiceCost; + pDestArrival->from_pos = i; + pDestArrival->from_slot = j + 1; + pDestArrival->match_len = k; + pDestArrival->num_literals = 0; + pDestArrival->score = nScore; + pDestArrival->rep_offset = nRepOffset; + pDestArrival->rep_pos = i; + pDestArrival->rep_len = k; + nRepLenHandledMask[k >> 3] &= ~(1 << (k & 7)); + } + } } } } + else { + break; + } } } - else { - break; - } + + if (k < nMaxRepInsertedLen) + nMinOverallRepLen = k; } } @@ -547,13 +663,16 @@ static void lzsa_optimize_forward_v2(lzsa_compressor *pCompressor, const unsigne } } - lzsa_arrival *end_arrival = &arrival[(i << MATCHES_PER_ARRIVAL_SHIFT) + 0]; + lzsa_arrival *end_arrival = &arrival[(i << ARRIVALS_PER_POSITION_SHIFT) + 0]; while (end_arrival->from_slot > 0 && end_arrival->from_pos >= 0) { if (end_arrival->from_pos >= nEndOffset) return; pBestMatch[end_arrival->from_pos].length = end_arrival->match_len; - pBestMatch[end_arrival->from_pos].offset = end_arrival->match_offset; - end_arrival = &arrival[(end_arrival->from_pos << MATCHES_PER_ARRIVAL_SHIFT) + (end_arrival->from_slot - 1)]; + if (end_arrival->match_len) + pBestMatch[end_arrival->from_pos].offset = end_arrival->rep_offset; + else + pBestMatch[end_arrival->from_pos].offset = 0; + end_arrival = &arrival[(end_arrival->from_pos << ARRIVALS_PER_POSITION_SHIFT) + (end_arrival->from_slot - 1)]; } } @@ -582,12 +701,12 @@ static int lzsa_optimize_command_count_v2(lzsa_compressor *pCompressor, const un lzsa_match *pMatch = pBestMatch + i; if (pMatch->length == 0 && - (i + 1) < (nEndOffset - LAST_LITERALS) && + (i + 1) < nEndOffset && pBestMatch[i + 1].length >= MIN_MATCH_SIZE_V2 && pBestMatch[i + 1].length < MAX_VARLEN && pBestMatch[i + 1].offset && i >= pBestMatch[i + 1].offset && - (i + pBestMatch[i + 1].length + 1) <= (nEndOffset - LAST_LITERALS) && + (i + pBestMatch[i + 1].length + 1) <= nEndOffset && !memcmp(pInWindow + i - (pBestMatch[i + 1].offset), pInWindow + i, pBestMatch[i + 1].length + 1)) { int nCurLenSize = lzsa_get_match_varlen_size_v2(pBestMatch[i + 1].length - MIN_MATCH_SIZE_V2); int nReducedLenSize = lzsa_get_match_varlen_size_v2(pBestMatch[i + 1].length + 1 - MIN_MATCH_SIZE_V2); @@ -623,7 +742,7 @@ static int lzsa_optimize_command_count_v2(lzsa_compressor *pCompressor, const un * matching large regions of identical bytes for instance, where there are too many offsets to be considered by the parser, and when not compressing to favor the * ratio (the forward arrivals parser already has this covered). */ if (i > nRepMatchOffset && - (i - nRepMatchOffset + pMatch->length) <= (nEndOffset - LAST_LITERALS) && + (i - nRepMatchOffset + pMatch->length) <= nEndOffset && !memcmp(pInWindow + i - nRepMatchOffset, pInWindow + i - pMatch->offset, pMatch->length)) { pMatch->offset = nRepMatchOffset; nDidReduce = 1; @@ -632,7 +751,7 @@ static int lzsa_optimize_command_count_v2(lzsa_compressor *pCompressor, const un if (pBestMatch[nNextIndex].offset && pMatch->offset != pBestMatch[nNextIndex].offset && nRepMatchOffset != pBestMatch[nNextIndex].offset) { /* Otherwise, try to gain a match forward as well */ - if (i > pBestMatch[nNextIndex].offset && (i - pBestMatch[nNextIndex].offset + pMatch->length) <= (nEndOffset - LAST_LITERALS)) { + if (i > pBestMatch[nNextIndex].offset && (i - pBestMatch[nNextIndex].offset + pMatch->length) <= nEndOffset) { int nMaxLen = 0; while (nMaxLen < pMatch->length && pInWindow[i - pBestMatch[nNextIndex].offset + nMaxLen] == pInWindow[i - pMatch->offset + nMaxLen]) nMaxLen++; @@ -675,20 +794,20 @@ static int lzsa_optimize_command_count_v2(lzsa_compressor *pCompressor, const un nCurCommandSize += (pMatch->offset <= 32) ? 4 : ((pMatch->offset <= 512) ? 8 : ((pMatch->offset <= (8192 + 512)) ? 12 : 16)); /* Calculate the next command's current cost */ - int nNextCommandSize = 8 /* token */ + lzsa_get_literals_varlen_size_v2(nNextLiterals) + (nNextLiterals << 3) + lzsa_get_match_varlen_size_v2(pBestMatch[nNextIndex].length - MIN_MATCH_SIZE_V2); + int nNextCommandSize = 8 /* token */ + lzsa_get_literals_varlen_size_v2(nNextLiterals) + /* (nNextLiterals << 3) + */ lzsa_get_match_varlen_size_v2(pBestMatch[nNextIndex].length - MIN_MATCH_SIZE_V2); if (pBestMatch[nNextIndex].offset != pMatch->offset) nNextCommandSize += (pBestMatch[nNextIndex].offset <= 32) ? 4 : ((pBestMatch[nNextIndex].offset <= 512) ? 8 : ((pBestMatch[nNextIndex].offset <= (8192 + 512)) ? 12 : 16)); int nOriginalCombinedCommandSize = nCurCommandSize + nNextCommandSize; /* Calculate the cost of replacing this match command by literals + the next command with the cost of encoding these literals (excluding 'nNumLiterals' bytes) */ - int nReducedCommandSize = (pMatch->length << 3) + 8 /* token */ + lzsa_get_literals_varlen_size_v2(nNumLiterals + pMatch->length + nNextLiterals) + (nNextLiterals << 3) + lzsa_get_match_varlen_size_v2(pBestMatch[nNextIndex].length - MIN_MATCH_SIZE_V2); + int nReducedCommandSize = (pMatch->length << 3) + 8 /* token */ + lzsa_get_literals_varlen_size_v2(nNumLiterals + pMatch->length + nNextLiterals) + /* (nNextLiterals << 3) + */ lzsa_get_match_varlen_size_v2(pBestMatch[nNextIndex].length - MIN_MATCH_SIZE_V2); if (pBestMatch[nNextIndex].offset != nRepMatchOffset) nReducedCommandSize += (pBestMatch[nNextIndex].offset <= 32) ? 4 : ((pBestMatch[nNextIndex].offset <= 512) ? 8 : ((pBestMatch[nNextIndex].offset <= (8192 + 512)) ? 12 : 16)); int nReplaceRepOffset = 0; if (nRepMatchOffset && nRepMatchOffset != nPrevRepMatchOffset && nRepMatchLen >= MIN_MATCH_SIZE_V2 && nRepMatchOffset != pBestMatch[nNextIndex].offset && nRepIndex > pBestMatch[nNextIndex].offset && - (nRepIndex - pBestMatch[nNextIndex].offset + nRepMatchLen) <= (nEndOffset - LAST_LITERALS) && + (nRepIndex - pBestMatch[nNextIndex].offset + nRepMatchLen) <= nEndOffset && !memcmp(pInWindow + nRepIndex - nRepMatchOffset, pInWindow + nRepIndex - pBestMatch[nNextIndex].offset, nRepMatchLen)) { /* Replacing this match command by literals would let us create a repmatch */ nReplaceRepOffset = 1; @@ -729,26 +848,30 @@ static int lzsa_optimize_command_count_v2(lzsa_compressor *pCompressor, const un pBestMatch[i + pMatch->length].length)) { int nNextIndex = i + pMatch->length; - int nNextLiterals = 0; while (nNextIndex < nEndOffset && pBestMatch[nNextIndex].length < MIN_MATCH_SIZE_V2) { - nNextLiterals++; nNextIndex++; } + int nNextOffset; + if (nNextIndex < nEndOffset) + nNextOffset = pBestMatch[nNextIndex].offset; + else + nNextOffset = 0; + int nCurPartialSize = lzsa_get_match_varlen_size_v2(pMatch->length - MIN_MATCH_SIZE_V2); - nCurPartialSize += 8 /* token */ + lzsa_get_literals_varlen_size_v2(0) + lzsa_get_match_varlen_size_v2(pBestMatch[i + pMatch->length].length - MIN_MATCH_SIZE_V2); + nCurPartialSize += 8 /* token */ + /* lzsa_get_literals_varlen_size_v2(0) + */ lzsa_get_match_varlen_size_v2(pBestMatch[i + pMatch->length].length - MIN_MATCH_SIZE_V2); if (pBestMatch[i + pMatch->length].offset != pMatch->offset) nCurPartialSize += (pBestMatch[i + pMatch->length].offset <= 32) ? 4 : ((pBestMatch[i + pMatch->length].offset <= 512) ? 8 : ((pBestMatch[i + pMatch->length].offset <= (8192 + 512)) ? 12 : 16)); - if (pBestMatch[nNextIndex].offset != pBestMatch[i + pMatch->length].offset) - nCurPartialSize += (pBestMatch[nNextIndex].offset <= 32) ? 4 : ((pBestMatch[nNextIndex].offset <= 512) ? 8 : ((pBestMatch[nNextIndex].offset <= (8192 + 512)) ? 12 : 16)); + if (nNextOffset != pBestMatch[i + pMatch->length].offset) + nCurPartialSize += (nNextOffset <= 32) ? 4 : ((nNextOffset <= 512) ? 8 : ((nNextOffset <= (8192 + 512)) ? 12 : 16)); int nReducedPartialSize = lzsa_get_match_varlen_size_v2(pMatch->length + pBestMatch[i + pMatch->length].length - MIN_MATCH_SIZE_V2); - if (pBestMatch[nNextIndex].offset != pMatch->offset) - nReducedPartialSize += (pBestMatch[nNextIndex].offset <= 32) ? 4 : ((pBestMatch[nNextIndex].offset <= 512) ? 8 : ((pBestMatch[nNextIndex].offset <= (8192 + 512)) ? 12 : 16)); + if (nNextOffset != pMatch->offset) + nReducedPartialSize += (nNextOffset <= 32) ? 4 : ((nNextOffset <= 512) ? 8 : ((nNextOffset <= (8192 + 512)) ? 12 : 16)); if (nCurPartialSize >= nReducedPartialSize) { int nMatchLen = pMatch->length; @@ -793,7 +916,6 @@ static int lzsa_optimize_command_count_v2(lzsa_compressor *pCompressor, const un static int lzsa_get_compressed_size_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMatch, const int nStartOffset, const int nEndOffset) { int i; int nNumLiterals = 0; - int nOutOffset = 0; int nRepMatchOffset = 0; int nCompressedSize = 0; @@ -838,7 +960,6 @@ static int lzsa_get_compressed_size_v2(lzsa_compressor *pCompressor, lzsa_match } { - int nTokenLiteralsLen = (nNumLiterals >= LITERALS_RUN_LEN_V2) ? LITERALS_RUN_LEN_V2 : nNumLiterals; int nCommandSize = 8 /* token */ + lzsa_get_literals_varlen_size_v2(nNumLiterals) + (nNumLiterals << 3); nCompressedSize += nCommandSize; @@ -846,7 +967,7 @@ static int lzsa_get_compressed_size_v2(lzsa_compressor *pCompressor, lzsa_match } if (pCompressor->flags & LZSA_FLAG_RAW_BLOCK) { - nCompressedSize += (8 + 4 + 8); + nCompressedSize += (8 + 4); } return nCompressedSize; @@ -870,7 +991,7 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa int nNumLiterals = 0; int nInFirstLiteralOffset = 0; int nOutOffset = 0; - int nCurNibbleOffset = -1, nCurFreeNibbles = 0; + int nCurNibbleOffset = -1; int nRepMatchOffset = 0; for (i = nStartOffset; i < nEndOffset; ) { @@ -916,7 +1037,7 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa return -1; pOutData[nOutOffset++] = nTokenOffsetMode | (nTokenLiteralsLen << 3) | nTokenMatchLen; - nOutOffset = lzsa_write_literals_varlen_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, nNumLiterals); + nOutOffset = lzsa_write_literals_varlen_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, nNumLiterals); if (nOutOffset < 0) return -1; if (nNumLiterals < pCompressor->stats.min_literals || pCompressor->stats.min_literals == -1) @@ -933,14 +1054,14 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa } if (nTokenOffsetMode == 0x00 || nTokenOffsetMode == 0x20) { - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, ((-nMatchOffset) & 0x1e) >> 1); + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, ((-nMatchOffset) & 0x1e) >> 1); if (nOutOffset < 0) return -1; } else if (nTokenOffsetMode == 0x40 || nTokenOffsetMode == 0x60) { pOutData[nOutOffset++] = (-nMatchOffset) & 0xff; } else if (nTokenOffsetMode == 0x80 || nTokenOffsetMode == 0xa0) { - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, ((-(nMatchOffset - 512)) >> 9) & 0x0f); + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, ((-(nMatchOffset - 512)) >> 9) & 0x0f); if (nOutOffset < 0) return -1; pOutData[nOutOffset++] = (-(nMatchOffset - 512)) & 0xff; } @@ -954,7 +1075,7 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa nRepMatchOffset = nMatchOffset; - nOutOffset = lzsa_write_match_varlen_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, nEncodedMatchLen); + nOutOffset = lzsa_write_match_varlen_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, nEncodedMatchLen); if (nOutOffset < 0) return -1; if (nMatchOffset < pCompressor->stats.min_offset || pCompressor->stats.min_offset == -1) @@ -1013,10 +1134,10 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa return -1; if (pCompressor->flags & LZSA_FLAG_RAW_BLOCK) - pOutData[nOutOffset++] = (nTokenLiteralsLen << 3) | 0x47; + pOutData[nOutOffset++] = (nTokenLiteralsLen << 3) | 0xe7; else pOutData[nOutOffset++] = (nTokenLiteralsLen << 3) | 0x00; - nOutOffset = lzsa_write_literals_varlen_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, nNumLiterals); + nOutOffset = lzsa_write_literals_varlen_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, nNumLiterals); if (nOutOffset < 0) return -1; if (nNumLiterals < pCompressor->stats.min_literals || pCompressor->stats.min_literals == -1) @@ -1046,9 +1167,8 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa if (nOutOffset >= nMaxOutDataSize) return -1; - pOutData[nOutOffset++] = 0; /* Match offset */ - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, 15); /* Extended match length nibble */ + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, 15); /* Extended match length nibble */ if (nOutOffset < 0) return -1; if ((nOutOffset + 1) > nMaxOutDataSize) @@ -1058,7 +1178,7 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa } if (nCurNibbleOffset != -1) { - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, 0); + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, 0); if (nOutOffset < 0 || nCurNibbleOffset != -1) return -1; } @@ -1079,19 +1199,19 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa * @return size of compressed data in output buffer, or -1 if the data is uncompressible */ static int lzsa_write_raw_uncompressed_block_v2(lzsa_compressor *pCompressor, const unsigned char *pInWindow, const int nStartOffset, const int nEndOffset, unsigned char *pOutData, const int nMaxOutDataSize) { - int nCurNibbleOffset = -1, nCurFreeNibbles = 0; + int nCurNibbleOffset = -1; int nNumLiterals = nEndOffset - nStartOffset; int nTokenLiteralsLen = (nNumLiterals >= LITERALS_RUN_LEN_V2) ? LITERALS_RUN_LEN_V2 : nNumLiterals; int nOutOffset = 0; - int nCommandSize = 8 /* token */ + lzsa_get_literals_varlen_size_v2(nNumLiterals) + (nNumLiterals << 3) + 8 + 4 + 8; + int nCommandSize = 8 /* token */ + lzsa_get_literals_varlen_size_v2(nNumLiterals) + (nNumLiterals << 3) + 4 + 8; if ((nOutOffset + ((nCommandSize + 7) >> 3)) > nMaxOutDataSize) return -1; pCompressor->num_commands = 0; - pOutData[nOutOffset++] = (nTokenLiteralsLen << 3) | 0x47; + pOutData[nOutOffset++] = (nTokenLiteralsLen << 3) | 0xe7; - nOutOffset = lzsa_write_literals_varlen_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, nNumLiterals); + nOutOffset = lzsa_write_literals_varlen_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, nNumLiterals); if (nOutOffset < 0) return -1; if (nNumLiterals != 0) { @@ -1102,9 +1222,7 @@ static int lzsa_write_raw_uncompressed_block_v2(lzsa_compressor *pCompressor, co /* Emit EOD marker for raw block */ - pOutData[nOutOffset++] = 0; /* Match offset */ - - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, 15); /* Extended match length nibble */ + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, 15); /* Extended match length nibble */ if (nOutOffset < 0) return -1; if ((nOutOffset + 1) > nMaxOutDataSize) @@ -1115,7 +1233,7 @@ static int lzsa_write_raw_uncompressed_block_v2(lzsa_compressor *pCompressor, co pCompressor->num_commands++; if (nCurNibbleOffset != -1) { - nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, &nCurFreeNibbles, 0); + nOutOffset = lzsa_write_nibble_v2(pOutData, nOutOffset, nMaxOutDataSize, &nCurNibbleOffset, 0); if (nOutOffset < 0 || nCurNibbleOffset != -1) return -1; } @@ -1137,12 +1255,27 @@ static int lzsa_write_raw_uncompressed_block_v2(lzsa_compressor *pCompressor, co */ int lzsa_optimize_and_write_block_v2(lzsa_compressor *pCompressor, const unsigned char *pInWindow, const int nPreviousBlockSize, const int nInDataSize, unsigned char *pOutData, const int nMaxOutDataSize) { int nResult, nBaseCompressedSize; - int nMatchesPerArrival = (nInDataSize < 65536) ? NMATCHES_PER_ARRIVAL_V2_BIG : NMATCHES_PER_ARRIVAL_V2_SMALL; + int nArrivalsPerPosition = (nInDataSize < 65536) ? NARRIVALS_PER_POSITION_V2_BIG : NARRIVALS_PER_POSITION_V2_SMALL; + int *rle_len = (int*)pCompressor->intervals /* reuse */; + int i; + + i = 0; + while (i < (nPreviousBlockSize + nInDataSize)) { + int nRangeStartIdx = i; + unsigned char c = pInWindow[nRangeStartIdx]; + do { + i++; + } while (i < (nPreviousBlockSize + nInDataSize) && pInWindow[i] == c); + while (nRangeStartIdx < i) { + rle_len[nRangeStartIdx] = i - nRangeStartIdx; + nRangeStartIdx++; + } + } /* Compress optimally without breaking ties in favor of less tokens */ memset(pCompressor->best_match, 0, BLOCK_SIZE * sizeof(lzsa_match)); - lzsa_optimize_forward_v2(pCompressor, pInWindow, pCompressor->best_match - nPreviousBlockSize, nPreviousBlockSize, nPreviousBlockSize + nInDataSize, 0 /* reduce */, (nInDataSize < 65536) ? 1 : 0 /* insert forward reps */, nMatchesPerArrival); + lzsa_optimize_forward_v2(pCompressor, pInWindow, pCompressor->best_match - nPreviousBlockSize, nPreviousBlockSize, nPreviousBlockSize + nInDataSize, 0 /* reduce */, (nInDataSize < 65536) ? 1 : 0 /* insert forward reps */, nArrivalsPerPosition); int nDidReduce; int nPasses = 0; @@ -1159,7 +1292,7 @@ int lzsa_optimize_and_write_block_v2(lzsa_compressor *pCompressor, const unsigne /* Compress optimally and do break ties in favor of less tokens */ memset(pCompressor->improved_match, 0, BLOCK_SIZE * sizeof(lzsa_match)); - lzsa_optimize_forward_v2(pCompressor, pInWindow, pCompressor->improved_match - nPreviousBlockSize, nPreviousBlockSize, nPreviousBlockSize + nInDataSize, 1 /* reduce */, 0 /* use forward reps */, nMatchesPerArrival); + lzsa_optimize_forward_v2(pCompressor, pInWindow, pCompressor->improved_match - nPreviousBlockSize, nPreviousBlockSize, nPreviousBlockSize + nInDataSize, 1 /* reduce */, 0 /* use forward reps */, nArrivalsPerPosition); nPasses = 0; do { @@ -1169,8 +1302,77 @@ int lzsa_optimize_and_write_block_v2(lzsa_compressor *pCompressor, const unsigne nReducedCompressedSize = lzsa_get_compressed_size_v2(pCompressor, pCompressor->improved_match - nPreviousBlockSize, nPreviousBlockSize, nPreviousBlockSize + nInDataSize); if (nReducedCompressedSize > 0 && nReducedCompressedSize <= nBaseCompressedSize) { + const int nEndOffset = nPreviousBlockSize + nInDataSize; + int nSupplementedCompressedSize; + /* Pick the parse with the reduced number of tokens as it didn't negatively affect the size */ pBestMatch = pCompressor->improved_match - nPreviousBlockSize; + + int* first_offset_for_byte = pCompressor->first_offset_for_byte; + int* next_offset_for_pos = pCompressor->next_offset_for_pos; + int nPosition; + + /* Supplement small matches */ + + memset(first_offset_for_byte, 0xff, sizeof(int) * 65536); + memset(next_offset_for_pos, 0xff, sizeof(int) * nInDataSize); + + for (nPosition = nPreviousBlockSize; nPosition < nEndOffset - 1; nPosition++) { + next_offset_for_pos[nPosition - nPreviousBlockSize] = first_offset_for_byte[((unsigned int)pInWindow[nPosition]) | (((unsigned int)pInWindow[nPosition + 1]) << 8)]; + first_offset_for_byte[((unsigned int)pInWindow[nPosition]) | (((unsigned int)pInWindow[nPosition + 1]) << 8)] = nPosition; + } + + for (nPosition = nPreviousBlockSize + 1; nPosition < (nEndOffset - 1); nPosition++) { + lzsa_match* match = pCompressor->match + ((nPosition - nPreviousBlockSize) << MATCHES_PER_INDEX_SHIFT_V2); + int m = 0, nInserted = 0; + int nMatchPos; + + while (m < 15 && match[m].length) + m++; + + for (nMatchPos = next_offset_for_pos[nPosition - nPreviousBlockSize]; m < 15 && nMatchPos >= 0; nMatchPos = next_offset_for_pos[nMatchPos - nPreviousBlockSize]) { + int nMatchOffset = nPosition - nMatchPos; + int nExistingMatchIdx; + int nAlreadyExists = 0; + + for (nExistingMatchIdx = 0; nExistingMatchIdx < m; nExistingMatchIdx++) { + if (match[nExistingMatchIdx].offset == nMatchOffset) { + nAlreadyExists = 1; + break; + } + } + + if (!nAlreadyExists) { + int nMatchLen = 2; + while (nMatchLen < 16 && (nPosition + nMatchLen + 4) < nEndOffset && !memcmp(pInWindow + nMatchPos + nMatchLen, pInWindow + nPosition + nMatchLen, 4)) + nMatchLen += 4; + while (nMatchLen < 16 && (nPosition + nMatchLen) < nEndOffset && pInWindow[nMatchPos + nMatchLen] == pInWindow[nPosition + nMatchLen]) + nMatchLen++; + match[m].length = nMatchLen; + match[m].offset = nMatchOffset; + m++; + nInserted++; + if (nInserted >= 15) + break; + } + } + } + + /* Compress optimally with the extra matches */ + memset(pCompressor->best_match, 0, BLOCK_SIZE * sizeof(lzsa_match)); + lzsa_optimize_forward_v2(pCompressor, pInWindow, pCompressor->best_match - nPreviousBlockSize, nPreviousBlockSize, nPreviousBlockSize + nInDataSize, 1 /* reduce */, 0 /* use forward reps */, nArrivalsPerPosition); + + nPasses = 0; + do { + nDidReduce = lzsa_optimize_command_count_v2(pCompressor, pInWindow, pCompressor->best_match - nPreviousBlockSize, nPreviousBlockSize, nPreviousBlockSize + nInDataSize); + nPasses++; + } while (nDidReduce && nPasses < 20); + + nSupplementedCompressedSize = lzsa_get_compressed_size_v2(pCompressor, pCompressor->best_match - nPreviousBlockSize, nPreviousBlockSize, nPreviousBlockSize + nInDataSize); + if (nSupplementedCompressedSize > 0 && nSupplementedCompressedSize < nReducedCompressedSize) { + /* Pick the parse with the extra matches as it didn't negatively affect the size */ + pBestMatch = pCompressor->best_match - nPreviousBlockSize; + } } } diff --git a/Tools/unix/lzsa/src/shrink_context.c b/Tools/unix/lzsa/src/shrink_context.c index c1e7ab3d..9e6900f7 100644 --- a/Tools/unix/lzsa/src/shrink_context.c +++ b/Tools/unix/lzsa/src/shrink_context.c @@ -62,6 +62,10 @@ int lzsa_compressor_init(lzsa_compressor *pCompressor, const int nMaxWindowSize, pCompressor->best_match = NULL; pCompressor->improved_match = NULL; pCompressor->arrival = NULL; + pCompressor->rep_slot_handled_mask = NULL; + pCompressor->rep_len_handled_mask = NULL; + pCompressor->first_offset_for_byte = NULL; + pCompressor->next_offset_for_pos = NULL; pCompressor->min_match_size = nMinMatchSize; if (pCompressor->min_match_size < nMinMatchSizeForFormat) pCompressor->min_match_size = nMinMatchSizeForFormat; @@ -89,7 +93,7 @@ int lzsa_compressor_init(lzsa_compressor *pCompressor, const int nMaxWindowSize, pCompressor->open_intervals = (unsigned int *)malloc((LCP_AND_TAG_MAX + 1) * sizeof(unsigned int)); if (pCompressor->open_intervals) { - pCompressor->arrival = (lzsa_arrival *)malloc(((BLOCK_SIZE + 1) << MATCHES_PER_ARRIVAL_SHIFT) * sizeof(lzsa_arrival)); + pCompressor->arrival = (lzsa_arrival *)malloc(((BLOCK_SIZE + 1) << ARRIVALS_PER_POSITION_SHIFT) * sizeof(lzsa_arrival)); if (pCompressor->arrival) { pCompressor->best_match = (lzsa_match *)malloc(BLOCK_SIZE * sizeof(lzsa_match)); @@ -102,8 +106,26 @@ int lzsa_compressor_init(lzsa_compressor *pCompressor, const int nMaxWindowSize, pCompressor->match = (lzsa_match *)malloc(BLOCK_SIZE * NMATCHES_PER_INDEX_V2 * sizeof(lzsa_match)); else pCompressor->match = (lzsa_match *)malloc(BLOCK_SIZE * NMATCHES_PER_INDEX_V1 * sizeof(lzsa_match)); - if (pCompressor->match) - return 0; + if (pCompressor->match) { + if (pCompressor->format_version == 2) { + pCompressor->rep_slot_handled_mask = (char*)malloc(NARRIVALS_PER_POSITION_V2_BIG * ((LCP_MAX + 1) / 8) * sizeof(char)); + if (pCompressor->rep_slot_handled_mask) { + pCompressor->rep_len_handled_mask = (char*)malloc(((LCP_MAX + 1) / 8) * sizeof(char)); + if (pCompressor->rep_len_handled_mask) { + pCompressor->first_offset_for_byte = (int*)malloc(65536 * sizeof(int)); + if (pCompressor->first_offset_for_byte) { + pCompressor->next_offset_for_pos = (int*)malloc(BLOCK_SIZE * sizeof(int)); + if (pCompressor->next_offset_for_pos) { + return 0; + } + } + } + } + } + else { + return 0; + } + } } } } @@ -124,6 +146,26 @@ int lzsa_compressor_init(lzsa_compressor *pCompressor, const int nMaxWindowSize, void lzsa_compressor_destroy(lzsa_compressor *pCompressor) { divsufsort_destroy(&pCompressor->divsufsort_context); + if (pCompressor->next_offset_for_pos) { + free(pCompressor->next_offset_for_pos); + pCompressor->next_offset_for_pos = NULL; + } + + if (pCompressor->first_offset_for_byte) { + free(pCompressor->first_offset_for_byte); + pCompressor->first_offset_for_byte = NULL; + } + + if (pCompressor->rep_len_handled_mask) { + free(pCompressor->rep_len_handled_mask); + pCompressor->rep_len_handled_mask = NULL; + } + + if (pCompressor->rep_slot_handled_mask) { + free(pCompressor->rep_slot_handled_mask); + pCompressor->rep_slot_handled_mask = NULL; + } + if (pCompressor->match) { free(pCompressor->match); pCompressor->match = NULL; diff --git a/Tools/unix/lzsa/src/shrink_context.h b/Tools/unix/lzsa/src/shrink_context.h index 70245cf6..ce80fbd2 100644 --- a/Tools/unix/lzsa/src/shrink_context.h +++ b/Tools/unix/lzsa/src/shrink_context.h @@ -49,10 +49,10 @@ extern "C" { #define VISITED_FLAG 0x80000000 #define EXCL_VISITED_MASK 0x7fffffff -#define NMATCHES_PER_ARRIVAL_V1 8 -#define NMATCHES_PER_ARRIVAL_V2_SMALL 9 -#define NMATCHES_PER_ARRIVAL_V2_BIG 32 -#define MATCHES_PER_ARRIVAL_SHIFT 5 +#define NARRIVALS_PER_POSITION_V1 8 +#define NARRIVALS_PER_POSITION_V2_SMALL 9 +#define NARRIVALS_PER_POSITION_V2_BIG 32 +#define ARRIVALS_PER_POSITION_SHIFT 5 #define NMATCHES_PER_INDEX_V1 8 #define MATCHES_PER_INDEX_SHIFT_V1 3 @@ -63,8 +63,6 @@ extern "C" { #define LEAVE_ALONE_MATCH_SIZE 300 #define LEAVE_ALONE_MATCH_SIZE_SMALL 1000 -#define LAST_LITERALS 0 - #define MODESWITCH_PENALTY 3 /** One match */ @@ -81,12 +79,10 @@ typedef struct { int from_pos; unsigned short rep_len; + unsigned short match_len; int rep_pos; int num_literals; int score; - - unsigned short match_offset; - unsigned short match_len; } lzsa_arrival; /** Compression statistics */ @@ -128,6 +124,10 @@ typedef struct _lzsa_compressor { lzsa_match *best_match; lzsa_match *improved_match; lzsa_arrival *arrival; + char *rep_slot_handled_mask; + char *rep_len_handled_mask; + int *first_offset_for_byte; + int *next_offset_for_pos; int min_match_size; int format_version; int flags; diff --git a/Tools/unix/uz80as/Makefile b/Tools/unix/uz80as/Makefile index 712c47b0..b99987aa 100644 --- a/Tools/unix/uz80as/Makefile +++ b/Tools/unix/uz80as/Makefile @@ -4,7 +4,7 @@ DEST = ../../`uname` CC = gcc -CFLAGS = -g +CFLAGS = -g -fcommon OBJECTS = ngetopt.o main.o options.o \ utils.o err.o incl.o sym.o \