From 890f9262e01297b404dba6d8e0ff5904e044d3db Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Wed, 22 Apr 2020 21:12:41 +1000 Subject: [PATCH 01/18] HBIOS: Added support for sound drivers New sound driver support with initial support for the SN76489 chip New build configuration entry: * SN76489ENABLE Ports are currently locked in with: * SN76489_PORT_LEFT .EQU $FC ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) * SN76489_PORT_RIGHT .EQU $F8 ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) --- Source/Doc/Architecture.md | 83 +++++ Source/HBIOS/Config/RCZ80_std.asm | 2 + Source/HBIOS/audio.inc | 26 ++ Source/HBIOS/cfg_dyno.asm | 3 + Source/HBIOS/cfg_ezz80.asm | 3 + Source/HBIOS/cfg_master.asm | 3 + Source/HBIOS/cfg_mk4.asm | 3 + Source/HBIOS/cfg_n8.asm | 3 + Source/HBIOS/cfg_rcz180.asm | 3 + Source/HBIOS/cfg_rcz80.asm | 3 + Source/HBIOS/cfg_sbc.asm | 3 + Source/HBIOS/cfg_scz180.asm | 3 + Source/HBIOS/cfg_zeta.asm | 3 + Source/HBIOS/cfg_zeta2.asm | 3 + Source/HBIOS/hbios.asm | 72 +++- Source/HBIOS/hbios.inc | 16 + Source/HBIOS/sn76489.asm | 588 ++++++++++++++++++++++++++++++ Source/HBIOS/std.asm | 89 ++--- Source/Makefile | 2 +- 19 files changed, 865 insertions(+), 46 deletions(-) create mode 100644 Source/HBIOS/audio.inc create mode 100644 Source/HBIOS/sn76489.asm diff --git a/Source/Doc/Architecture.md b/Source/Doc/Architecture.md index 90d531ba..eb962567 100644 --- a/Source/Doc/Architecture.md +++ b/Source/Doc/Architecture.md @@ -1292,6 +1292,81 @@ codes as described at the start of this section. `\clearpage`{=latex} +Sound (SND) +------------ + +### Function 0x50 -- Sound Reset (SNDRESET) + +| _Entry Parameters_ +| B: 0x50 +| C: The audio device unit number + +| _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: The audio device unit number +| L: The volume to be applied (00=Silence, FF=Maximum) + +| _Exit Results_ +| A: Status (0=OK, else error) + +This function set the volume configuration command. The volume will +be applied when the SNDPLAY function is invoked. + +### Function 0x52 -- Sound Volume (SNDPIT) + +| _Entry Parameters_ +| B: 0x52 +| C: The audio device unit number +| HL: The pitch to be applied (0000=lowest note, FFFF=highest note) + +This function set the pitch configuration command. The pitch will +be applied when the SNDPLAY function is invoked. + +### Function 0x53 -- Sound Volume (SNDNOTE) + +| _Entry Parameters_ +| B: 0x52 +| C: The audio device unit number +| L: A number from 0 to 255 selecting quarter notes + +This function will apply a pitch value to the sound chip. + +The value correspond to standard musical notes. The value allows for selection +of a quarter of a semitone by giving a value between 0 and upto the drivers maximum +supported value. The lowest note is (0). + +For the SN76490 chip, 0 corresponds to note A1# and the value 249 is the maximum +supported value, and it corresponds to note C7. + +### Function 0x54 -- Sound Play (SNDPLAY) + +| _Entry Parameters_ +| B: 0x53 +| C: The audio device unit number +| D: The channel to play the previously configured tone + +This function set the pitch and volume previously configured with the SNDPIT +and SNDVOL functions. + +For example, to play a specific note, on the first installed driver, 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 +``` + +`\clearpage`{=latex} + System (SYS) ------------ @@ -1573,6 +1648,14 @@ available along with the registers/information used as input. | _Returned Values_ | A: Status (0=OK, else error) +#### SYSSET Subfunction 0xD2 -- Inc Timer (TIMER) + +| _Entry Parameters_ +| BC: 0xF9D2 + +| _Returned Values_ +| A: Status (0=OK, else error) + #### SYSSET Subfunction 0xE0 -- Set Boot Information (BOOTINFO) diff --git a/Source/HBIOS/Config/RCZ80_std.asm b/Source/HBIOS/Config/RCZ80_std.asm index da88345f..5b120cb7 100644 --- a/Source/HBIOS/Config/RCZ80_std.asm +++ b/Source/HBIOS/Config/RCZ80_std.asm @@ -38,3 +38,5 @@ 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) + +SN76489ENABLE .SET FALSE ; SN76489 SOUND DRIVER diff --git a/Source/HBIOS/audio.inc b/Source/HBIOS/audio.inc new file mode 100644 index 00000000..e171eb41 --- /dev/null +++ b/Source/HBIOS/audio.inc @@ -0,0 +1,26 @@ +#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_DE PUSH DE \ PUSH DE \ POP HL \ CALL PRTHEXWORDHL \ POP DE +#DEFINE AUDTRACE_IY PUSH HL \ PUSH IY \ POP HL \ CALL PRTHEXWORDHL \ POP HL + +#DEFINE AUDDEBUG(S) CALL PRTSTRD \ .TEXT S \ .TEXT "$" ; $$$$$$ PRINT STRING S TO CONSOLE - PRTD("HELLO") - NO TRAILING $ REQUIRED + +#ELSE +#DEFINE AUDTRACE(S) +#DEFINE AUDTRACE_A +#DEFINE AUDTRACE_B +#DEFINE AUDTRACE_D +#DEFINE AUDTRACE_E +#DEFINE AUDTRACE_L +#DEFINE AUDTRACE_HL +#DEFINE AUDTRACE_DE +#DEFINE AUDTRACE_IY + +#DEFINE AUDDEBUG(STR) +#ENDIF diff --git a/Source/HBIOS/cfg_dyno.asm b/Source/HBIOS/cfg_dyno.asm index 13714081..01c0f32b 100644 --- a/Source/HBIOS/cfg_dyno.asm +++ b/Source/HBIOS/cfg_dyno.asm @@ -154,3 +154,6 @@ PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_ezz80.asm b/Source/HBIOS/cfg_ezz80.asm index 9784be32..385ca6d7 100644 --- a/Source/HBIOS/cfg_ezz80.asm +++ b/Source/HBIOS/cfg_ezz80.asm @@ -179,3 +179,6 @@ PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm index 52bd69d2..a4cf63d5 100644 --- a/Source/HBIOS/cfg_master.asm +++ b/Source/HBIOS/cfg_master.asm @@ -234,3 +234,6 @@ 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 + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index 6cfd61bc..191128bd 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -188,3 +188,6 @@ 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 + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index 26ff3331..48362ebf 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -188,3 +188,6 @@ 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 + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_rcz180.asm b/Source/HBIOS/cfg_rcz180.asm index f099c2cf..18037ad3 100644 --- a/Source/HBIOS/cfg_rcz180.asm +++ b/Source/HBIOS/cfg_rcz180.asm @@ -188,3 +188,6 @@ PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_rcz80.asm b/Source/HBIOS/cfg_rcz80.asm index f94c1694..02a35956 100644 --- a/Source/HBIOS/cfg_rcz80.asm +++ b/Source/HBIOS/cfg_rcz80.asm @@ -194,3 +194,6 @@ PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index 0c7e2170..60b8675d 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -190,3 +190,6 @@ 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 + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_scz180.asm b/Source/HBIOS/cfg_scz180.asm index 41af5fb4..e16892a0 100644 --- a/Source/HBIOS/cfg_scz180.asm +++ b/Source/HBIOS/cfg_scz180.asm @@ -183,3 +183,6 @@ PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index ca9dfb7e..6a3982a7 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -134,3 +134,6 @@ PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/cfg_zeta2.asm b/Source/HBIOS/cfg_zeta2.asm index 1192d8d5..e5422759 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -144,3 +144,6 @@ PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) + +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 55ed757e..81404dcf 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1647,6 +1647,9 @@ HB_PCINITTBLLEN .EQU (($ - HB_PCINITTBL) / 2) ;================================================================================================== ; HB_INITTBL: +#IF (SN76489ENABLE) + .DW SN76489_INIT +#ENDIF #IF (CTCENABLE) .DW CTC_INIT #ENDIF @@ -1731,6 +1734,7 @@ HB_INITTBL: #IF (UFENABLE) .DW UF_INIT #ENDIF + ; HB_INITTBLLEN .EQU (($ - HB_INITTBL) / 2) ; @@ -1794,6 +1798,10 @@ HB_DISPCALL: CALL C,PANIC ; OBSOLETE! 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 JP SYS_DISPATCH ; OTHERWISE SYS CALL @@ -2154,7 +2162,7 @@ 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 ; @@ -2219,6 +2227,51 @@ 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 + +; +; +;================================================================================================== +; 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 6 ; NUMBER OF SND FUNCS (FOR RANGE CHECK) +SND_MAX .EQU 2 ; 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 @@ -2359,6 +2412,8 @@ SYS_GET: JR Z,SYS_GETDIOCNT CP BF_SYSGET_VDACNT JR Z,SYS_GETVDACNT + CP BF_SYSGET_SNDCNT + JR Z, SYS_GETSNDCNT CP BF_SYSGET_TIMER JR Z,SYS_GETTIMER CP BF_SYSGET_SECS @@ -2477,6 +2532,13 @@ SYS_GETVDACNT: LD E,A ; PUT IT IN E XOR A ; SIGNALS SUCCESS RET + +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 + ; ; SET SYSTEM PARAMETERS ; PARAMETER(S) TO SET INDICATED IN C @@ -3250,6 +3312,14 @@ 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 ; #DEFINE USEDELAY #INCLUDE "util.asm" diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index 6c166307..477fcdfe 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -51,6 +51,21 @@ BF_VDASCR .EQU BF_VDA + 11 ; SCROLL 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_SNDPIT .EQU BF_SND + 2 ; REQUEST SOUND PITCH - HL CONTAINS PITCH 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 ; D IS CHANNEL, E IS SUBCOMMAND + +; BF_SNDQUERY SUBCOMMANDS +SND_STATUS .EQU 0 +SND_CHCNT .EQU SND_STATUS + 1 ; RETURN COUNT OF CHANNELS +SND_SVOLUME .EQU SND_STATUS + 2 ; 8 BIT NUMBER +SND_SPITCH .EQU SND_STATUS + 3 ; 16 BIT NUMBER + ; BF_SYS .EQU $F0 BF_SYSRESET .EQU BF_SYS + 0 ; SOFT RESET HBIOS @@ -70,6 +85,7 @@ BF_SYSINT .EQU BF_SYS + 12 ; MANAGE INTERRUPT VECTORS BF_SYSGET_CIOCNT .EQU $00 ; GET CHAR UNIT COUNT BF_SYSGET_DIOCNT .EQU $10 ; GET DISK UNIT COUNT BF_SYSGET_VDACNT .EQU $40 ; GET VDA UNIT COUNT +BF_SYSGET_SNDCNT .EQU $50 ; GET VDA UNIT COUNT 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 diff --git a/Source/HBIOS/sn76489.asm b/Source/HBIOS/sn76489.asm new file mode 100644 index 00000000..68928dfb --- /dev/null +++ b/Source/HBIOS/sn76489.asm @@ -0,0 +1,588 @@ +;====================================================================== +; SN76489 sound driver +; +; WRITTEN BY: DEAN NETHERTON +;====================================================================== +; +; TODO: +; +;====================================================================== +; CONSTANTS +;====================================================================== +; + +SN76489_PORT_LEFT .EQU $FC ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) +SN76489_PORT_RIGHT .EQU $F8 ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) +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 + +SN7CLKDIVIDER .EQU 4 +SN7CLK .EQU CPUOSC / SN7CLKDIVIDER +SN7RATIO .EQU SN7CLK * 100 / 32 + + +SN7_FIRST_NOTE .EQU 5827 ; A1# +SN7_LAST_NODE .EQU 209300 ; C7 + +A1S .equ SN7RATIO / SN7_FIRST_NOTE +C7 .EQU SN7RATIO / SN7_LAST_NODE + + .echo "SN76489: range of A1# (pitch: " + .echo A1S + .echo ") to C7 (pitch: " + .echo C7 + .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(TRACE_INIT) + CALL SN7_VOLUME_OFF + XOR A ; SIGNAL SUCCESS + RET + +SN7_VOLUME_OFF: + AUDTRACE(TRACE_VOLUME_OFF) + + 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 + +; BITS MAPING +; SET TONE: +; 1 CC 0 PPPP (LOW) +; 0 0 PPPPPP (HIGH) + +; 1 CC 1 VVVV + +SN7_VOLUME: + AUDDEBUG("SN7VOL ") + AUDTRACE_L + AUDDEBUG("\r\n") + LD A, L + LD (PENDING_VOLUME), A + + XOR A ; SIGNAL SUCCESS + RET + + + +SN7_NOTE: + AUDDEBUG("SN7NOT ") + AUDTRACE_L + AUDDEBUG("\r\n") + + ADD HL, HL ; SHIFT RIGHT (MULT 2) -INDEX INTO SN7NOTETBL TABLE OF WORDS + ; TEST IF HL IS LARGER THAN SN7NOTETBL SIZE + OR A ; CLEAR CARRY FLAG + LD DE, SIZ_SN7NOTETBL + SBC HL, DE + JR NC, SN7_NOTE1 ; INCOMING HL DOES NOT MAP INTO SN7NOTETBL + + ADD HL, DE ; RESTORE HL + LD E, L ; HL = SN7NOTETBL + HL + LD D, H + LD HL, SN7NOTETBL + ADD HL, DE + + LD A, (HL) ; RETRIEVE PITCH COUNT FROM SN7NOTETBL + INC HL + LD H, (HL) + LD L, A + + JR SN7_PITCH ; APPLY PITCH + +SN7_NOTE1: + OR $FF ; not implemented yet + RET + +SN7_PITCH: + AUDDEBUG("SN7PIT ") + AUDTRACE_HL + AUDDEBUG("\r\n") + LD (PENDING_PITCH), HL + + XOR A ; SIGNAL SUCCESS + RET + +SN7_PLAY: + AUDDEBUG("SN7PLY ") + AUDTRACE_D + AUDDEBUG("\r\n") + + CALL SN7_APPLY_VOL + CALL SN7_APPLY_PIT + + XOR A ; SIGNAL SUCCESS + RET + +SN7_QUERY: + LD A, E + CP SND_CHCNT + JR Z, SN7_QUERY_CHCNT + + CP SND_SPITCH + JR Z, SN7_QUERY_PITCH + + CP SND_SVOLUME + JR Z, SN7_QUERY_VOLUME + + OR $FF ; SIGNAL FAILURE + RET + +SN7_QUERY_CHCNT: + LD B, SN7_TONECNT + LD C, SN7_NOISECNT + XOR A + RET + +SN7_QUERY_PITCH: + LD HL, (PENDING_PITCH) + + XOR A + RET + +SN7_QUERY_VOLUME: + LD A, (PENDING_VOLUME) + LD L, A + LD H, 0 + + 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, (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(TRACE_PORT_WR) + AUDTRACE_A + AUDTRACE(TRACE_NEWLINE) + + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + POP AF + POP BC + RET + +SN7_APPLY_PIT: + PUSH DE + PUSH BC + PUSH AF + LD HL, (PENDING_PITCH) + + LD A, D + AND $3 + RLCA + RLCA + RLCA + RLCA + RLCA + OR $80 + LD B, A ; PITCH COMMAND 1 - CONTAINS CHANNEL ONLY + + LD A, L ; GET LOWER 4 BITS FOR COMMAND 1 + AND $F + OR B ; A NOW CONATINS FIRST PITCH COMMAND + + AUDTRACE(TRACE_PORT_WR) + AUDTRACE_A + AUDTRACE(TRACE_NEWLINE) + + 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 PITCH COMMAND + + AUDTRACE(TRACE_PORT_WR) + AUDTRACE_A + AUDTRACE(TRACE_NEWLINE) + + OUT (SN76489_PORT_LEFT), A + OUT (SN76489_PORT_RIGHT), A + + POP AF + POP BC + POP DE + RET + + +SN7_FNTBL: + .DW SN7_RESET + .DW SN7_VOLUME + .DW SN7_PITCH + .DW SN7_NOTE + .DW SN7_PLAY + .DW SN7_QUERY + +#IF (($ - SN7_FNTBL) != (SND_FNCNT * 2)) + .ECHO "*** INVALID SND FUNCTION TABLE ***\n" + FAIL +#ENDIF + +PENDING_PITCH + .DW 0 ; PENDING PITCH (10 BITS) +PENDING_VOLUME + .DB 0 ; PENDING VOL (8 BITS -> downoverted to 4 BITS and inverted) + +STR_MESSAGELT .DB "\r\nSN76489: LEFT IO=0x$" +STR_MESSAGERT .DB ", RIGHT IO=0x$" + +#IF AUDIOTRACE +TRACE_INIT .DB "\r\nSN7_INIT CALLED\r\n$" +TRACE_VOLUME_OFF .DB "\r\nSN7_VOLUME_OFF\r\n$" +TRACE_VOLUME_SET .DB "\r\nSN7_VOLUME_SET CH: $" +TRACE_PLAY .DB "\r\nPLAY\r\n$" +TRACE_VOLUME .DB ", VOL: $" +TRACE_PORT_WR .DB "\r\nOUT SN76489, $" +TRACE_PITCH_SET .DB "\r\nSN7_PITCH_SET CH: $" +TRACE_PITCH .DB ", PITCH: $" +TRACE_NEWLINE .DB "\r\n$" +#ENDIF + +; THE FREQUENCY BY QUATER TONE STARTING AT A1# +SN7NOTETBL: + .dw A1S + .dw SN7RATIO / 5912 + .dw SN7RATIO / 5998 + .dw SN7RATIO / 6085 + .dw SN7RATIO / 6174 + .dw SN7RATIO / 6264 + .dw SN7RATIO / 6355 + .dw SN7RATIO / 6447 + .dw SN7RATIO / 6541 + .dw SN7RATIO / 6636 + .dw SN7RATIO / 6733 + .dw SN7RATIO / 6831 + .dw SN7RATIO / 6930 + .dw SN7RATIO / 7031 + .dw SN7RATIO / 7133 + .dw SN7RATIO / 7237 + .dw SN7RATIO / 7342 + .dw SN7RATIO / 7449 + .dw SN7RATIO / 7557 + .dw SN7RATIO / 7667 + .dw SN7RATIO / 7778 + .dw SN7RATIO / 7891 + .dw SN7RATIO / 8006 + .dw SN7RATIO / 8122 + .dw SN7RATIO / 8241 + .dw SN7RATIO / 8361 + .dw SN7RATIO / 8482 + .dw SN7RATIO / 8606 + .dw SN7RATIO / 8731 + .dw SN7RATIO / 8858 + .dw SN7RATIO / 8987 + .dw SN7RATIO / 9118 + .dw SN7RATIO / 9250 + .dw SN7RATIO / 9385 + .dw SN7RATIO / 9521 + .dw SN7RATIO / 9660 + .dw SN7RATIO / 9800 + .dw SN7RATIO / 9943 + .dw SN7RATIO / 10087 + .dw SN7RATIO / 10234 + .dw SN7RATIO / 10383 + .dw SN7RATIO / 10534 + .dw SN7RATIO / 10687 + .dw SN7RATIO / 10843 + .dw SN7RATIO / 11000 + .dw SN7RATIO / 11160 + .dw SN7RATIO / 11322 + .dw SN7RATIO / 11487 + .dw SN7RATIO / 11654 + .dw SN7RATIO / 11824 + .dw SN7RATIO / 11995 + .dw SN7RATIO / 12170 + .dw SN7RATIO / 12347 + .dw SN7RATIO / 12527 + .dw SN7RATIO / 12709 + .dw SN7RATIO / 12894 + .dw SN7RATIO / 13081 + .dw SN7RATIO / 13271 + .dw SN7RATIO / 13464 + .dw SN7RATIO / 13660 + .dw SN7RATIO / 13859 + .dw SN7RATIO / 14061 + .dw SN7RATIO / 14265 + .dw SN7RATIO / 14473 + .dw SN7RATIO / 14683 + .dw SN7RATIO / 14897 + .dw SN7RATIO / 15113 + .dw SN7RATIO / 15333 + .dw SN7RATIO / 15556 + .dw SN7RATIO / 15782 + .dw SN7RATIO / 16012 + .dw SN7RATIO / 16245 + .dw SN7RATIO / 16481 + .dw SN7RATIO / 16721 + .dw SN7RATIO / 16964 + .dw SN7RATIO / 17211 + .dw SN7RATIO / 17461 + .dw SN7RATIO / 17715 + .dw SN7RATIO / 17973 + .dw SN7RATIO / 18234 + .dw SN7RATIO / 18500 + .dw SN7RATIO / 18769 + .dw SN7RATIO / 19042 + .dw SN7RATIO / 19319 + .dw SN7RATIO / 19600 + .dw SN7RATIO / 19885 + .dw SN7RATIO / 20174 + .dw SN7RATIO / 20468 + .dw SN7RATIO / 20765 + .dw SN7RATIO / 21067 + .dw SN7RATIO / 21373 + .dw SN7RATIO / 21684 + .dw SN7RATIO / 22000 + .dw SN7RATIO / 22320 + .dw SN7RATIO / 22645 + .dw SN7RATIO / 22974 + .dw SN7RATIO / 23308 + .dw SN7RATIO / 23647 + .dw SN7RATIO / 23991 + .dw SN7RATIO / 24340 + .dw SN7RATIO / 24694 + .dw SN7RATIO / 25053 + .dw SN7RATIO / 25418 + .dw SN7RATIO / 25787 + .dw SN7RATIO / 26163 + .dw SN7RATIO / 26544 + .dw SN7RATIO / 26930 + .dw SN7RATIO / 27321 + .dw SN7RATIO / 27718 + .dw SN7RATIO / 28121 + .dw SN7RATIO / 28530 + .dw SN7RATIO / 28945 + .dw SN7RATIO / 29366 + .dw SN7RATIO / 29793 + .dw SN7RATIO / 30226 + .dw SN7RATIO / 30666 + .dw SN7RATIO / 31113 + .dw SN7RATIO / 31566 + .dw SN7RATIO / 32025 + .dw SN7RATIO / 32490 + .dw SN7RATIO / 32963 + .dw SN7RATIO / 33442 + .dw SN7RATIO / 33929 + .dw SN7RATIO / 34422 + .dw SN7RATIO / 34923 + .dw SN7RATIO / 35431 + .dw SN7RATIO / 35946 + .dw SN7RATIO / 36469 + .dw SN7RATIO / 36999 + .dw SN7RATIO / 37537 + .dw SN7RATIO / 38083 + .dw SN7RATIO / 38637 + .dw SN7RATIO / 39200 + .dw SN7RATIO / 39770 + .dw SN7RATIO / 40349 + .dw SN7RATIO / 40936 + .dw SN7RATIO / 41530 + .dw SN7RATIO / 42134 + .dw SN7RATIO / 42747 + .dw SN7RATIO / 43369 + .dw SN7RATIO / 44000 + .dw SN7RATIO / 44640 + .dw SN7RATIO / 45289 + .dw SN7RATIO / 45948 + .dw SN7RATIO / 46616 + .dw SN7RATIO / 47294 + .dw SN7RATIO / 47982 + .dw SN7RATIO / 48680 + .dw SN7RATIO / 49388 + .dw SN7RATIO / 50106 + .dw SN7RATIO / 50835 + .dw SN7RATIO / 51575 + .dw SN7RATIO / 52325 + .dw SN7RATIO / 53086 + .dw SN7RATIO / 53858 + .dw SN7RATIO / 54642 + .dw SN7RATIO / 55437 + .dw SN7RATIO / 56243 + .dw SN7RATIO / 57061 + .dw SN7RATIO / 57891 + .dw SN7RATIO / 58733 + .dw SN7RATIO / 59587 + .dw SN7RATIO / 60454 + .dw SN7RATIO / 61333 + .dw SN7RATIO / 62225 + .dw SN7RATIO / 63130 + .dw SN7RATIO / 64048 + .dw SN7RATIO / 64980 + .dw SN7RATIO / 65925 + .dw SN7RATIO / 66884 + .dw SN7RATIO / 67857 + .dw SN7RATIO / 68844 + .dw SN7RATIO / 69846 + .dw SN7RATIO / 70862 + .dw SN7RATIO / 71893 + .dw SN7RATIO / 72938 + .dw SN7RATIO / 73999 + .dw SN7RATIO / 75075 + .dw SN7RATIO / 76167 + .dw SN7RATIO / 77275 + .dw SN7RATIO / 78399 + .dw SN7RATIO / 79539 + .dw SN7RATIO / 80696 + .dw SN7RATIO / 81870 + .dw SN7RATIO / 83061 + .dw SN7RATIO / 84269 + .dw SN7RATIO / 85495 + .dw SN7RATIO / 86738 + .dw SN7RATIO / 88000 + .dw SN7RATIO / 89280 + .dw SN7RATIO / 90579 + .dw SN7RATIO / 91896 + .dw SN7RATIO / 93233 + .dw SN7RATIO / 94589 + .dw SN7RATIO / 95965 + .dw SN7RATIO / 97361 + .dw SN7RATIO / 98777 + .dw SN7RATIO / 100214 + .dw SN7RATIO / 101671 + .dw SN7RATIO / 103150 + .dw SN7RATIO / 104650 + .dw SN7RATIO / 106172 + .dw SN7RATIO / 107716 + .dw SN7RATIO / 109283 + .dw SN7RATIO / 110873 + .dw SN7RATIO / 112486 + .dw SN7RATIO / 114122 + .dw SN7RATIO / 115782 + .dw SN7RATIO / 117466 + .dw SN7RATIO / 119175 + .dw SN7RATIO / 120908 + .dw SN7RATIO / 122667 + .dw SN7RATIO / 124451 + .dw SN7RATIO / 126261 + .dw SN7RATIO / 128098 + .dw SN7RATIO / 129961 + .dw SN7RATIO / 131851 + .dw SN7RATIO / 133769 + .dw SN7RATIO / 135715 + .dw SN7RATIO / 137689 + .dw SN7RATIO / 139691 + .dw SN7RATIO / 141723 + .dw SN7RATIO / 143784 + .dw SN7RATIO / 145876 + .dw SN7RATIO / 147998 + .dw SN7RATIO / 150151 + .dw SN7RATIO / 152335 + .dw SN7RATIO / 154550 + .dw SN7RATIO / 156798 + .dw SN7RATIO / 159079 + .dw SN7RATIO / 161393 + .dw SN7RATIO / 163740 + .dw SN7RATIO / 166122 + .dw SN7RATIO / 168538 + .dw SN7RATIO / 170990 + .dw SN7RATIO / 173477 + .dw SN7RATIO / 176000 + .dw SN7RATIO / 178560 + .dw SN7RATIO / 181157 + .dw SN7RATIO / 183792 + .dw SN7RATIO / 186466 + .dw SN7RATIO / 189178 + .dw SN7RATIO / 191930 + .dw SN7RATIO / 194722 + .dw SN7RATIO / 197553 + .dw SN7RATIO / 200426 + .dw SN7RATIO / 203342 + .dw SN7RATIO / 206299 + .dw C7 + +SIZ_SN7NOTETBL .EQU $ - SN7NOTETBL + .ECHO "SN76489 approx " + .ECHO SIZ_SN7NOTETBL / 2 / 4 /12 + .ECHO " Octaves. Last note index supported: " + + .echo SIZ_SN7NOTETBL / 2 + .echo "\n" diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 1ba9f27f..93015bd8 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; @@ -207,7 +207,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 @@ -217,34 +217,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 @@ -254,27 +254,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. @@ -304,7 +304,7 @@ 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 @@ -430,7 +430,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 @@ -462,7 +462,7 @@ 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 @@ -477,7 +477,7 @@ 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 @@ -488,6 +488,7 @@ INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B #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/Makefile b/Source/Makefile index 166bb4c1..63c4204f 100644 --- a/Source/Makefile +++ b/Source/Makefile @@ -2,7 +2,7 @@ # order is actually important, because of build dependencies # SUBDIRS = Prop -SUBDIRS += Apps +SUBDIRS += Apps SUBDIRS += CBIOS SUBDIRS += Forth SUBDIRS += Fonts From d14cf27acfec0f14803d873505486e826bbbf6d5 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Wed, 22 Apr 2020 11:26:32 -0700 Subject: [PATCH 02/18] Miscellaneous Cleanup No functional changes. --- Doc/ChangeLog.txt | 2 + Doc/RomWBW Applications.pdf | Bin 140215 -> 140215 bytes Doc/RomWBW Architecture.pdf | Bin 371105 -> 396943 bytes Doc/RomWBW Getting Started.pdf | Bin 166096 -> 166220 bytes ReadMe.md | 7 +- ReadMe.txt | 7 +- Source/Doc/Architecture.md | 72 ++-- Source/Doc/GettingStarted.md | 5 +- Source/HBIOS/Config/RCZ80_std.asm | 2 +- Source/HBIOS/audio.inc | 52 +-- Source/HBIOS/cfg_dyno.asm | 4 +- Source/HBIOS/cfg_ezz80.asm | 4 +- Source/HBIOS/cfg_master.asm | 4 +- Source/HBIOS/cfg_mk4.asm | 4 +- Source/HBIOS/cfg_n8.asm | 4 +- Source/HBIOS/cfg_rcz180.asm | 4 +- Source/HBIOS/cfg_sbc.asm | 4 +- Source/HBIOS/cfg_scz180.asm | 4 +- Source/HBIOS/cfg_zeta.asm | 4 +- Source/HBIOS/cfg_zeta2.asm | 4 +- Source/HBIOS/hbios.asm | 20 +- Source/HBIOS/hbios.inc | 13 +- Source/HBIOS/sn76489.asm | 552 +++++++++++++++--------------- Source/HBIOS/std.asm | 24 +- Source/HBIOS/util.asm | 11 + Source/ver.inc | 2 +- Source/ver.lib | 2 +- 27 files changed, 425 insertions(+), 386 deletions(-) diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index 1d48213c..50f5f407 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -9,6 +9,8 @@ Version 3.1 - 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 +- D?N: Added sound driver support +- D?N: Added SN76489 sound chip driver Version 3.0.1 ------------- diff --git a/Doc/RomWBW Applications.pdf b/Doc/RomWBW Applications.pdf index 4fdbaee45f2fef4c43fd928b2e3d648a992e9479..8bc1135e2ed68689ef93bf92ab3df4f12e39df52 100644 GIT binary patch delta 113 zcmdmfoMZcOj)pCa>c2RQj0_D8O-u}?>;GbuhV!-u{bFR*bT%|Hbu}^pLPujKBPUlg fQ$sUHR~J)9V>e?XQ%4skI|Um;N~X_JW|9Q}87CcE delta 113 zcmdmfoMZcOj)pCa>c2P)O${tf3=9pY>;GbuhV!-u{bFR*bT+qibaXXyG&C?acCs*b gGIlX=wJ>%zH?(lHa5Z)@H?UK%A*5vbEM+EH042vAZvX%Q diff --git a/Doc/RomWBW Architecture.pdf b/Doc/RomWBW Architecture.pdf index 3987650cb0c1a45e1c25ec5c58535bb99b65496d..9c90a8d0e791023bd75a7ca534350613db0c9138 100644 GIT binary patch delta 70567 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

`JJc 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 delta 48158 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 diff --git a/Doc/RomWBW Getting Started.pdf b/Doc/RomWBW Getting Started.pdf index 2329e301f157737df240a3d604a963483c960098..99f132330355482b09020140ded9efafc6749e35 100644 GIT binary patch delta 10568 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 delta 10485 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 diff --git a/ReadMe.md b/ReadMe.md index 030e20e5..0ef34b7f 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -3,7 +3,7 @@ ## Z80/Z180 System Software Version 3.1 Pre-release -Wednesday 15 April 2020 +Wednesday 22 April 2020 Wayne Warthen @@ -1141,8 +1141,11 @@ applications are no longer provided. 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. + - Dean Netherton contributed the sound driver interface and the + SN76489 sound driver. Contributions of all kinds to RomWBW are very welcome. diff --git a/ReadMe.txt b/ReadMe.txt index e0241d40..4337d2cb 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -3,7 +3,7 @@ RomWBW Z80/Z180 System Software Version 3.1 Pre-release -Wednesday 15 April 2020 +Wednesday 22 April 2020 Wayne Warthen wwarthen@gmail.com @@ -1173,8 +1173,11 @@ applications are no longer provided. 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. +- Dean Netherton contributed the sound driver interface and the + SN76489 sound driver. Contributions of all kinds to RomWBW are very welcome. diff --git a/Source/Doc/Architecture.md b/Source/Doc/Architecture.md index eb962567..94c9a85d 100644 --- a/Source/Doc/Architecture.md +++ b/Source/Doc/Architecture.md @@ -1299,7 +1299,7 @@ Sound (SND) | _Entry Parameters_ | B: 0x50 -| C: The audio device unit number +| C: Audio Device Unit ID | _Exit Results_ | A: Status (0=OK, else error) @@ -1311,53 +1311,62 @@ channels to silence. | _Entry Parameters_ | B: 0x51 -| C: The audio device unit number -| L: The volume to be applied (00=Silence, FF=Maximum) +| C: Audio Device Unit ID +| L: Volume (00=Silence, FF=Maximum) | _Exit Results_ | A: Status (0=OK, else error) -This function set the volume configuration command. The volume will -be applied when the SNDPLAY function is invoked. +This function sets the sound chip volume parameter. The volume will +be applied when the next SNDPLAY function is invoked. -### Function 0x52 -- Sound Volume (SNDPIT) +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 Pitch (SNDPIT) | _Entry Parameters_ | B: 0x52 -| C: The audio device unit number -| HL: The pitch to be applied (0000=lowest note, FFFF=highest note) +| C: Audio Device Unit ID +| HL: Pitch (0000=lowest note, FFFF=highest note) + +This function sets the sound chip pitch parameter. The pitch will +be applied when the next SNDPLAY function is invoked. -This function set the pitch configuration command. The pitch will -be applied when the SNDPLAY function is invoked. +The pitch value is a driver specific value. To play standardized +notes, use the SNDNOTE function. -### Function 0x53 -- Sound Volume (SNDNOTE) +### Function 0x53 -- Sound Note (SNDNOTE) | _Entry Parameters_ -| B: 0x52 -| C: The audio device unit number -| L: A number from 0 to 255 selecting quarter notes +| B: 0x53 +| C: Audio Device Unit ID +| L: Note (0 to 255 quarter notes) -This function will apply a pitch value to the sound chip. +This function sets the sound chip pitch parameter according to +standardized notes. -The value correspond to standard musical notes. The value allows for selection -of a quarter of a semitone by giving a value between 0 and upto the drivers maximum -supported value. The lowest note is (0). +The value corresponds to standard musical notes. The value allows +for selection of a quarter of a semitone by giving a value between 0 +and up to the drivers maximum supported value. The lowest note is (0). -For the SN76490 chip, 0 corresponds to note A1# and the value 249 is the maximum -supported value, and it corresponds to note C7. +For the SN76490 chip, 0 corresponds to note A1# and the value 249 is +the maximum supported value, and it corresponds to note C7. ### Function 0x54 -- Sound Play (SNDPLAY) | _Entry Parameters_ -| B: 0x53 -| C: The audio device unit number -| D: The channel to play the previously configured tone +| B: 0x54 +| C: Audio Device Unit ID +| D: Channel -This function set the pitch and volume previously configured with the SNDPIT -and SNDVOL functions. +This function applies the previously specified volume and pitch 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 the first installed driver, the following -HBIOS calls would need to be made +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 @@ -1555,6 +1564,15 @@ available along with the registers/information returned. | A: Status (0=OK, else error) | E: Count of Video Device Units +#### 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 0xD0 -- Get Timer Tick Count (TIMER) | _Entry Parameters_ diff --git a/Source/Doc/GettingStarted.md b/Source/Doc/GettingStarted.md index a92b189a..4148a245 100644 --- a/Source/Doc/GettingStarted.md +++ b/Source/Doc/GettingStarted.md @@ -1194,8 +1194,11 @@ platform. 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. +* Dean Netherton contributed the sound driver interface and +the SN76489 sound driver. Contributions of all kinds to RomWBW are very welcome. diff --git a/Source/HBIOS/Config/RCZ80_std.asm b/Source/HBIOS/Config/RCZ80_std.asm index 5b120cb7..5766331e 100644 --- a/Source/HBIOS/Config/RCZ80_std.asm +++ b/Source/HBIOS/Config/RCZ80_std.asm @@ -38,5 +38,5 @@ 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) - +; SN76489ENABLE .SET FALSE ; SN76489 SOUND DRIVER diff --git a/Source/HBIOS/audio.inc b/Source/HBIOS/audio.inc index e171eb41..e1a9fbe4 100644 --- a/Source/HBIOS/audio.inc +++ b/Source/HBIOS/audio.inc @@ -1,26 +1,26 @@ -#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_DE PUSH DE \ PUSH DE \ POP HL \ CALL PRTHEXWORDHL \ POP DE -#DEFINE AUDTRACE_IY PUSH HL \ PUSH IY \ POP HL \ CALL PRTHEXWORDHL \ POP HL - -#DEFINE AUDDEBUG(S) CALL PRTSTRD \ .TEXT S \ .TEXT "$" ; $$$$$$ PRINT STRING S TO CONSOLE - PRTD("HELLO") - NO TRAILING $ REQUIRED - -#ELSE -#DEFINE AUDTRACE(S) -#DEFINE AUDTRACE_A -#DEFINE AUDTRACE_B -#DEFINE AUDTRACE_D -#DEFINE AUDTRACE_E -#DEFINE AUDTRACE_L -#DEFINE AUDTRACE_HL -#DEFINE AUDTRACE_DE -#DEFINE AUDTRACE_IY - -#DEFINE AUDDEBUG(STR) -#ENDIF +#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_DE PUSH DE \ PUSH DE \ POP HL \ CALL PRTHEXWORDHL \ POP DE +#DEFINE AUDTRACE_IY PUSH HL \ PUSH IY \ POP HL \ CALL PRTHEXWORDHL \ POP HL + +#DEFINE AUDDEBUG(S) CALL PRTSTRD \ .TEXT S \ .TEXT "$" ; $$$$$$ PRINT STRING S TO CONSOLE - PRTD("HELLO") - NO TRAILING $ REQUIRED + +#ELSE +#DEFINE AUDTRACE(S) +#DEFINE AUDTRACE_A +#DEFINE AUDTRACE_B +#DEFINE AUDTRACE_D +#DEFINE AUDTRACE_E +#DEFINE AUDTRACE_L +#DEFINE AUDTRACE_HL +#DEFINE AUDTRACE_DE +#DEFINE AUDTRACE_IY + +#DEFINE AUDDEBUG(STR) +#ENDIF diff --git a/Source/HBIOS/cfg_dyno.asm b/Source/HBIOS/cfg_dyno.asm index 01c0f32b..8226482d 100644 --- a/Source/HBIOS/cfg_dyno.asm +++ b/Source/HBIOS/cfg_dyno.asm @@ -155,5 +155,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_ezz80.asm b/Source/HBIOS/cfg_ezz80.asm index 385ca6d7..990d2e1d 100644 --- a/Source/HBIOS/cfg_ezz80.asm +++ b/Source/HBIOS/cfg_ezz80.asm @@ -180,5 +180,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm index a4cf63d5..faafae4e 100644 --- a/Source/HBIOS/cfg_master.asm +++ b/Source/HBIOS/cfg_master.asm @@ -235,5 +235,5 @@ 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 -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index 191128bd..8e23bf25 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -189,5 +189,5 @@ 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 -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index 48362ebf..7cb9a714 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -189,5 +189,5 @@ 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 -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_rcz180.asm b/Source/HBIOS/cfg_rcz180.asm index 18037ad3..fcdf9d72 100644 --- a/Source/HBIOS/cfg_rcz180.asm +++ b/Source/HBIOS/cfg_rcz180.asm @@ -189,5 +189,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index 60b8675d..e682bc01 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -191,5 +191,5 @@ 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 -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_scz180.asm b/Source/HBIOS/cfg_scz180.asm index e16892a0..07d679ce 100644 --- a/Source/HBIOS/cfg_scz180.asm +++ b/Source/HBIOS/cfg_scz180.asm @@ -184,5 +184,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index 6a3982a7..93dcb107 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -135,5 +135,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_zeta2.asm b/Source/HBIOS/cfg_zeta2.asm index e5422759..e42d0503 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -145,5 +145,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP ; UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) -SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER -AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER \ No newline at end of file +SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 81404dcf..3af09e56 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1030,7 +1030,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 @@ -1098,17 +1098,17 @@ 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 ; @@ -1647,9 +1647,6 @@ HB_PCINITTBLLEN .EQU (($ - HB_PCINITTBL) / 2) ;================================================================================================== ; HB_INITTBL: -#IF (SN76489ENABLE) - .DW SN76489_INIT -#ENDIF #IF (CTCENABLE) .DW CTC_INIT #ENDIF @@ -1659,6 +1656,9 @@ HB_INITTBL: #IF (AYENABLE) .DW AY_INIT ; AUDIBLE INDICATOR OF BOOT START #ENDIF +#IF (SN76489ENABLE) + .DW SN76489_INIT +#ENDIF #IF (ASCIENABLE) .DW ASCI_INIT #ENDIF @@ -3959,7 +3959,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 diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index 477fcdfe..17a9ae23 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -51,7 +51,7 @@ BF_VDASCR .EQU BF_VDA + 11 ; SCROLL 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) @@ -59,13 +59,12 @@ BF_SNDPIT .EQU BF_SND + 2 ; REQUEST SOUND PITCH - HL CONTAINS PITCH DRIVER SPECI 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 ; D IS CHANNEL, E IS SUBCOMMAND - +; ; BF_SNDQUERY SUBCOMMANDS -SND_STATUS .EQU 0 -SND_CHCNT .EQU SND_STATUS + 1 ; RETURN COUNT OF CHANNELS -SND_SVOLUME .EQU SND_STATUS + 2 ; 8 BIT NUMBER -SND_SPITCH .EQU SND_STATUS + 3 ; 16 BIT NUMBER - +BF_SNDQ_STATUS .EQU 0 +BF_SNDQ_CHCNT .EQU BF_SNDQ_STATUS + 1 ; RETURN COUNT OF CHANNELS +BF_SNDQ_SVOLUME .EQU BF_SNDQ_STATUS + 2 ; 8 BIT NUMBER +BF_SNDQ_SPITCH .EQU BF_SNDQ_STATUS + 3 ; 16 BIT NUMBER ; BF_SYS .EQU $F0 BF_SYSRESET .EQU BF_SYS + 0 ; SOFT RESET HBIOS diff --git a/Source/HBIOS/sn76489.asm b/Source/HBIOS/sn76489.asm index 68928dfb..18f7f649 100644 --- a/Source/HBIOS/sn76489.asm +++ b/Source/HBIOS/sn76489.asm @@ -11,9 +11,9 @@ ;====================================================================== ; -SN76489_PORT_LEFT .EQU $FC ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) -SN76489_PORT_RIGHT .EQU $F8 ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) -SN7_IDAT .EQU 0 +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 @@ -23,33 +23,33 @@ CHANNEL_2_SILENT .EQU $DF CHANNEL_3_SILENT .EQU $FF SN7CLKDIVIDER .EQU 4 -SN7CLK .EQU CPUOSC / SN7CLKDIVIDER +SN7CLK .EQU CPUOSC / SN7CLKDIVIDER SN7RATIO .EQU SN7CLK * 100 / 32 SN7_FIRST_NOTE .EQU 5827 ; A1# -SN7_LAST_NODE .EQU 209300 ; C7 +SN7_LAST_NOTE .EQU 209300 ; C7 -A1S .equ SN7RATIO / SN7_FIRST_NOTE -C7 .EQU SN7RATIO / SN7_LAST_NODE +A1S .EQU SN7RATIO / SN7_FIRST_NOTE +C7 .EQU SN7RATIO / SN7_LAST_NOTE - .echo "SN76489: range of A1# (pitch: " - .echo A1S - .echo ") to C7 (pitch: " - .echo C7 - .echo ")\n" + .ECHO "SN76489: range of A1# (pitch: " + .ECHO A1S + .ECHO ") to C7 (pitch: " + .ECHO C7 + .ECHO ")\n" -#include "audio.inc" +#INCLUDE "audio.inc" SN76489_INIT: LD IY, SN7_IDAT ; POINTER TO INSTANCE DATA - LD DE,STR_MESSAGELT + LD DE,STR_MESSAGELT CALL WRITESTR LD A, SN76489_PORT_LEFT CALL PRTHEXBYTE - LD DE,STR_MESSAGERT + LD DE,STR_MESSAGERT CALL WRITESTR LD A, SN76489_PORT_RIGHT CALL PRTHEXBYTE @@ -95,7 +95,7 @@ SN7_VOLUME_OFF: RET -; BITS MAPING +; BIT MAPPING ; SET TONE: ; 1 CC 0 PPPP (LOW) ; 0 0 PPPPPP (HIGH) @@ -121,10 +121,10 @@ SN7_NOTE: ADD HL, HL ; SHIFT RIGHT (MULT 2) -INDEX INTO SN7NOTETBL TABLE OF WORDS ; TEST IF HL IS LARGER THAN SN7NOTETBL SIZE - OR A ; CLEAR CARRY FLAG + OR A ; CLEAR CARRY FLAG LD DE, SIZ_SN7NOTETBL - SBC HL, DE - JR NC, SN7_NOTE1 ; INCOMING HL DOES NOT MAP INTO SN7NOTETBL + SBC HL, DE + JR NC, SN7_NOTE1 ; INCOMING HL DOES NOT MAP INTO SN7NOTETBL ADD HL, DE ; RESTORE HL LD E, L ; HL = SN7NOTETBL + HL @@ -140,7 +140,7 @@ SN7_NOTE: JR SN7_PITCH ; APPLY PITCH SN7_NOTE1: - OR $FF ; not implemented yet + OR $FF ; NOT IMPLEMENTED YET RET SN7_PITCH: @@ -165,13 +165,13 @@ SN7_PLAY: SN7_QUERY: LD A, E - CP SND_CHCNT + CP BF_SNDQ_CHCNT JR Z, SN7_QUERY_CHCNT - CP SND_SPITCH + CP BF_SNDQ_SPITCH JR Z, SN7_QUERY_PITCH - CP SND_SVOLUME + CP BF_SNDQ_SVOLUME JR Z, SN7_QUERY_VOLUME OR $FF ; SIGNAL FAILURE @@ -310,7 +310,7 @@ SN7_FNTBL: PENDING_PITCH .DW 0 ; PENDING PITCH (10 BITS) PENDING_VOLUME - .DB 0 ; PENDING VOL (8 BITS -> downoverted to 4 BITS and inverted) + .DB 0 ; PENDING VOL (8 BITS -> DOWNOVERTED TO 4 BITS AND INVERTED) STR_MESSAGELT .DB "\r\nSN76489: LEFT IO=0x$" STR_MESSAGERT .DB ", RIGHT IO=0x$" @@ -324,265 +324,265 @@ TRACE_VOLUME .DB ", VOL: $" TRACE_PORT_WR .DB "\r\nOUT SN76489, $" TRACE_PITCH_SET .DB "\r\nSN7_PITCH_SET CH: $" TRACE_PITCH .DB ", PITCH: $" -TRACE_NEWLINE .DB "\r\n$" +TRACE_NEWLINE .DB "\r\n$" #ENDIF ; THE FREQUENCY BY QUATER TONE STARTING AT A1# SN7NOTETBL: - .dw A1S - .dw SN7RATIO / 5912 - .dw SN7RATIO / 5998 - .dw SN7RATIO / 6085 - .dw SN7RATIO / 6174 - .dw SN7RATIO / 6264 - .dw SN7RATIO / 6355 - .dw SN7RATIO / 6447 - .dw SN7RATIO / 6541 - .dw SN7RATIO / 6636 - .dw SN7RATIO / 6733 - .dw SN7RATIO / 6831 - .dw SN7RATIO / 6930 - .dw SN7RATIO / 7031 - .dw SN7RATIO / 7133 - .dw SN7RATIO / 7237 - .dw SN7RATIO / 7342 - .dw SN7RATIO / 7449 - .dw SN7RATIO / 7557 - .dw SN7RATIO / 7667 - .dw SN7RATIO / 7778 - .dw SN7RATIO / 7891 - .dw SN7RATIO / 8006 - .dw SN7RATIO / 8122 - .dw SN7RATIO / 8241 - .dw SN7RATIO / 8361 - .dw SN7RATIO / 8482 - .dw SN7RATIO / 8606 - .dw SN7RATIO / 8731 - .dw SN7RATIO / 8858 - .dw SN7RATIO / 8987 - .dw SN7RATIO / 9118 - .dw SN7RATIO / 9250 - .dw SN7RATIO / 9385 - .dw SN7RATIO / 9521 - .dw SN7RATIO / 9660 - .dw SN7RATIO / 9800 - .dw SN7RATIO / 9943 - .dw SN7RATIO / 10087 - .dw SN7RATIO / 10234 - .dw SN7RATIO / 10383 - .dw SN7RATIO / 10534 - .dw SN7RATIO / 10687 - .dw SN7RATIO / 10843 - .dw SN7RATIO / 11000 - .dw SN7RATIO / 11160 - .dw SN7RATIO / 11322 - .dw SN7RATIO / 11487 - .dw SN7RATIO / 11654 - .dw SN7RATIO / 11824 - .dw SN7RATIO / 11995 - .dw SN7RATIO / 12170 - .dw SN7RATIO / 12347 - .dw SN7RATIO / 12527 - .dw SN7RATIO / 12709 - .dw SN7RATIO / 12894 - .dw SN7RATIO / 13081 - .dw SN7RATIO / 13271 - .dw SN7RATIO / 13464 - .dw SN7RATIO / 13660 - .dw SN7RATIO / 13859 - .dw SN7RATIO / 14061 - .dw SN7RATIO / 14265 - .dw SN7RATIO / 14473 - .dw SN7RATIO / 14683 - .dw SN7RATIO / 14897 - .dw SN7RATIO / 15113 - .dw SN7RATIO / 15333 - .dw SN7RATIO / 15556 - .dw SN7RATIO / 15782 - .dw SN7RATIO / 16012 - .dw SN7RATIO / 16245 - .dw SN7RATIO / 16481 - .dw SN7RATIO / 16721 - .dw SN7RATIO / 16964 - .dw SN7RATIO / 17211 - .dw SN7RATIO / 17461 - .dw SN7RATIO / 17715 - .dw SN7RATIO / 17973 - .dw SN7RATIO / 18234 - .dw SN7RATIO / 18500 - .dw SN7RATIO / 18769 - .dw SN7RATIO / 19042 - .dw SN7RATIO / 19319 - .dw SN7RATIO / 19600 - .dw SN7RATIO / 19885 - .dw SN7RATIO / 20174 - .dw SN7RATIO / 20468 - .dw SN7RATIO / 20765 - .dw SN7RATIO / 21067 - .dw SN7RATIO / 21373 - .dw SN7RATIO / 21684 - .dw SN7RATIO / 22000 - .dw SN7RATIO / 22320 - .dw SN7RATIO / 22645 - .dw SN7RATIO / 22974 - .dw SN7RATIO / 23308 - .dw SN7RATIO / 23647 - .dw SN7RATIO / 23991 - .dw SN7RATIO / 24340 - .dw SN7RATIO / 24694 - .dw SN7RATIO / 25053 - .dw SN7RATIO / 25418 - .dw SN7RATIO / 25787 - .dw SN7RATIO / 26163 - .dw SN7RATIO / 26544 - .dw SN7RATIO / 26930 - .dw SN7RATIO / 27321 - .dw SN7RATIO / 27718 - .dw SN7RATIO / 28121 - .dw SN7RATIO / 28530 - .dw SN7RATIO / 28945 - .dw SN7RATIO / 29366 - .dw SN7RATIO / 29793 - .dw SN7RATIO / 30226 - .dw SN7RATIO / 30666 - .dw SN7RATIO / 31113 - .dw SN7RATIO / 31566 - .dw SN7RATIO / 32025 - .dw SN7RATIO / 32490 - .dw SN7RATIO / 32963 - .dw SN7RATIO / 33442 - .dw SN7RATIO / 33929 - .dw SN7RATIO / 34422 - .dw SN7RATIO / 34923 - .dw SN7RATIO / 35431 - .dw SN7RATIO / 35946 - .dw SN7RATIO / 36469 - .dw SN7RATIO / 36999 - .dw SN7RATIO / 37537 - .dw SN7RATIO / 38083 - .dw SN7RATIO / 38637 - .dw SN7RATIO / 39200 - .dw SN7RATIO / 39770 - .dw SN7RATIO / 40349 - .dw SN7RATIO / 40936 - .dw SN7RATIO / 41530 - .dw SN7RATIO / 42134 - .dw SN7RATIO / 42747 - .dw SN7RATIO / 43369 - .dw SN7RATIO / 44000 - .dw SN7RATIO / 44640 - .dw SN7RATIO / 45289 - .dw SN7RATIO / 45948 - .dw SN7RATIO / 46616 - .dw SN7RATIO / 47294 - .dw SN7RATIO / 47982 - .dw SN7RATIO / 48680 - .dw SN7RATIO / 49388 - .dw SN7RATIO / 50106 - .dw SN7RATIO / 50835 - .dw SN7RATIO / 51575 - .dw SN7RATIO / 52325 - .dw SN7RATIO / 53086 - .dw SN7RATIO / 53858 - .dw SN7RATIO / 54642 - .dw SN7RATIO / 55437 - .dw SN7RATIO / 56243 - .dw SN7RATIO / 57061 - .dw SN7RATIO / 57891 - .dw SN7RATIO / 58733 - .dw SN7RATIO / 59587 - .dw SN7RATIO / 60454 - .dw SN7RATIO / 61333 - .dw SN7RATIO / 62225 - .dw SN7RATIO / 63130 - .dw SN7RATIO / 64048 - .dw SN7RATIO / 64980 - .dw SN7RATIO / 65925 - .dw SN7RATIO / 66884 - .dw SN7RATIO / 67857 - .dw SN7RATIO / 68844 - .dw SN7RATIO / 69846 - .dw SN7RATIO / 70862 - .dw SN7RATIO / 71893 - .dw SN7RATIO / 72938 - .dw SN7RATIO / 73999 - .dw SN7RATIO / 75075 - .dw SN7RATIO / 76167 - .dw SN7RATIO / 77275 - .dw SN7RATIO / 78399 - .dw SN7RATIO / 79539 - .dw SN7RATIO / 80696 - .dw SN7RATIO / 81870 - .dw SN7RATIO / 83061 - .dw SN7RATIO / 84269 - .dw SN7RATIO / 85495 - .dw SN7RATIO / 86738 - .dw SN7RATIO / 88000 - .dw SN7RATIO / 89280 - .dw SN7RATIO / 90579 - .dw SN7RATIO / 91896 - .dw SN7RATIO / 93233 - .dw SN7RATIO / 94589 - .dw SN7RATIO / 95965 - .dw SN7RATIO / 97361 - .dw SN7RATIO / 98777 - .dw SN7RATIO / 100214 - .dw SN7RATIO / 101671 - .dw SN7RATIO / 103150 - .dw SN7RATIO / 104650 - .dw SN7RATIO / 106172 - .dw SN7RATIO / 107716 - .dw SN7RATIO / 109283 - .dw SN7RATIO / 110873 - .dw SN7RATIO / 112486 - .dw SN7RATIO / 114122 - .dw SN7RATIO / 115782 - .dw SN7RATIO / 117466 - .dw SN7RATIO / 119175 - .dw SN7RATIO / 120908 - .dw SN7RATIO / 122667 - .dw SN7RATIO / 124451 - .dw SN7RATIO / 126261 - .dw SN7RATIO / 128098 - .dw SN7RATIO / 129961 - .dw SN7RATIO / 131851 - .dw SN7RATIO / 133769 - .dw SN7RATIO / 135715 - .dw SN7RATIO / 137689 - .dw SN7RATIO / 139691 - .dw SN7RATIO / 141723 - .dw SN7RATIO / 143784 - .dw SN7RATIO / 145876 - .dw SN7RATIO / 147998 - .dw SN7RATIO / 150151 - .dw SN7RATIO / 152335 - .dw SN7RATIO / 154550 - .dw SN7RATIO / 156798 - .dw SN7RATIO / 159079 - .dw SN7RATIO / 161393 - .dw SN7RATIO / 163740 - .dw SN7RATIO / 166122 - .dw SN7RATIO / 168538 - .dw SN7RATIO / 170990 - .dw SN7RATIO / 173477 - .dw SN7RATIO / 176000 - .dw SN7RATIO / 178560 - .dw SN7RATIO / 181157 - .dw SN7RATIO / 183792 - .dw SN7RATIO / 186466 - .dw SN7RATIO / 189178 - .dw SN7RATIO / 191930 - .dw SN7RATIO / 194722 - .dw SN7RATIO / 197553 - .dw SN7RATIO / 200426 - .dw SN7RATIO / 203342 - .dw SN7RATIO / 206299 - .dw C7 + .DW A1S + .DW SN7RATIO / 5912 + .DW SN7RATIO / 5998 + .DW SN7RATIO / 6085 + .DW SN7RATIO / 6174 + .DW SN7RATIO / 6264 + .DW SN7RATIO / 6355 + .DW SN7RATIO / 6447 + .DW SN7RATIO / 6541 + .DW SN7RATIO / 6636 + .DW SN7RATIO / 6733 + .DW SN7RATIO / 6831 + .DW SN7RATIO / 6930 + .DW SN7RATIO / 7031 + .DW SN7RATIO / 7133 + .DW SN7RATIO / 7237 + .DW SN7RATIO / 7342 + .DW SN7RATIO / 7449 + .DW SN7RATIO / 7557 + .DW SN7RATIO / 7667 + .DW SN7RATIO / 7778 + .DW SN7RATIO / 7891 + .DW SN7RATIO / 8006 + .DW SN7RATIO / 8122 + .DW SN7RATIO / 8241 + .DW SN7RATIO / 8361 + .DW SN7RATIO / 8482 + .DW SN7RATIO / 8606 + .DW SN7RATIO / 8731 + .DW SN7RATIO / 8858 + .DW SN7RATIO / 8987 + .DW SN7RATIO / 9118 + .DW SN7RATIO / 9250 + .DW SN7RATIO / 9385 + .DW SN7RATIO / 9521 + .DW SN7RATIO / 9660 + .DW SN7RATIO / 9800 + .DW SN7RATIO / 9943 + .DW SN7RATIO / 10087 + .DW SN7RATIO / 10234 + .DW SN7RATIO / 10383 + .DW SN7RATIO / 10534 + .DW SN7RATIO / 10687 + .DW SN7RATIO / 10843 + .DW SN7RATIO / 11000 + .DW SN7RATIO / 11160 + .DW SN7RATIO / 11322 + .DW SN7RATIO / 11487 + .DW SN7RATIO / 11654 + .DW SN7RATIO / 11824 + .DW SN7RATIO / 11995 + .DW SN7RATIO / 12170 + .DW SN7RATIO / 12347 + .DW SN7RATIO / 12527 + .DW SN7RATIO / 12709 + .DW SN7RATIO / 12894 + .DW SN7RATIO / 13081 + .DW SN7RATIO / 13271 + .DW SN7RATIO / 13464 + .DW SN7RATIO / 13660 + .DW SN7RATIO / 13859 + .DW SN7RATIO / 14061 + .DW SN7RATIO / 14265 + .DW SN7RATIO / 14473 + .DW SN7RATIO / 14683 + .DW SN7RATIO / 14897 + .DW SN7RATIO / 15113 + .DW SN7RATIO / 15333 + .DW SN7RATIO / 15556 + .DW SN7RATIO / 15782 + .DW SN7RATIO / 16012 + .DW SN7RATIO / 16245 + .DW SN7RATIO / 16481 + .DW SN7RATIO / 16721 + .DW SN7RATIO / 16964 + .DW SN7RATIO / 17211 + .DW SN7RATIO / 17461 + .DW SN7RATIO / 17715 + .DW SN7RATIO / 17973 + .DW SN7RATIO / 18234 + .DW SN7RATIO / 18500 + .DW SN7RATIO / 18769 + .DW SN7RATIO / 19042 + .DW SN7RATIO / 19319 + .DW SN7RATIO / 19600 + .DW SN7RATIO / 19885 + .DW SN7RATIO / 20174 + .DW SN7RATIO / 20468 + .DW SN7RATIO / 20765 + .DW SN7RATIO / 21067 + .DW SN7RATIO / 21373 + .DW SN7RATIO / 21684 + .DW SN7RATIO / 22000 + .DW SN7RATIO / 22320 + .DW SN7RATIO / 22645 + .DW SN7RATIO / 22974 + .DW SN7RATIO / 23308 + .DW SN7RATIO / 23647 + .DW SN7RATIO / 23991 + .DW SN7RATIO / 24340 + .DW SN7RATIO / 24694 + .DW SN7RATIO / 25053 + .DW SN7RATIO / 25418 + .DW SN7RATIO / 25787 + .DW SN7RATIO / 26163 + .DW SN7RATIO / 26544 + .DW SN7RATIO / 26930 + .DW SN7RATIO / 27321 + .DW SN7RATIO / 27718 + .DW SN7RATIO / 28121 + .DW SN7RATIO / 28530 + .DW SN7RATIO / 28945 + .DW SN7RATIO / 29366 + .DW SN7RATIO / 29793 + .DW SN7RATIO / 30226 + .DW SN7RATIO / 30666 + .DW SN7RATIO / 31113 + .DW SN7RATIO / 31566 + .DW SN7RATIO / 32025 + .DW SN7RATIO / 32490 + .DW SN7RATIO / 32963 + .DW SN7RATIO / 33442 + .DW SN7RATIO / 33929 + .DW SN7RATIO / 34422 + .DW SN7RATIO / 34923 + .DW SN7RATIO / 35431 + .DW SN7RATIO / 35946 + .DW SN7RATIO / 36469 + .DW SN7RATIO / 36999 + .DW SN7RATIO / 37537 + .DW SN7RATIO / 38083 + .DW SN7RATIO / 38637 + .DW SN7RATIO / 39200 + .DW SN7RATIO / 39770 + .DW SN7RATIO / 40349 + .DW SN7RATIO / 40936 + .DW SN7RATIO / 41530 + .DW SN7RATIO / 42134 + .DW SN7RATIO / 42747 + .DW SN7RATIO / 43369 + .DW SN7RATIO / 44000 + .DW SN7RATIO / 44640 + .DW SN7RATIO / 45289 + .DW SN7RATIO / 45948 + .DW SN7RATIO / 46616 + .DW SN7RATIO / 47294 + .DW SN7RATIO / 47982 + .DW SN7RATIO / 48680 + .DW SN7RATIO / 49388 + .DW SN7RATIO / 50106 + .DW SN7RATIO / 50835 + .DW SN7RATIO / 51575 + .DW SN7RATIO / 52325 + .DW SN7RATIO / 53086 + .DW SN7RATIO / 53858 + .DW SN7RATIO / 54642 + .DW SN7RATIO / 55437 + .DW SN7RATIO / 56243 + .DW SN7RATIO / 57061 + .DW SN7RATIO / 57891 + .DW SN7RATIO / 58733 + .DW SN7RATIO / 59587 + .DW SN7RATIO / 60454 + .DW SN7RATIO / 61333 + .DW SN7RATIO / 62225 + .DW SN7RATIO / 63130 + .DW SN7RATIO / 64048 + .DW SN7RATIO / 64980 + .DW SN7RATIO / 65925 + .DW SN7RATIO / 66884 + .DW SN7RATIO / 67857 + .DW SN7RATIO / 68844 + .DW SN7RATIO / 69846 + .DW SN7RATIO / 70862 + .DW SN7RATIO / 71893 + .DW SN7RATIO / 72938 + .DW SN7RATIO / 73999 + .DW SN7RATIO / 75075 + .DW SN7RATIO / 76167 + .DW SN7RATIO / 77275 + .DW SN7RATIO / 78399 + .DW SN7RATIO / 79539 + .DW SN7RATIO / 80696 + .DW SN7RATIO / 81870 + .DW SN7RATIO / 83061 + .DW SN7RATIO / 84269 + .DW SN7RATIO / 85495 + .DW SN7RATIO / 86738 + .DW SN7RATIO / 88000 + .DW SN7RATIO / 89280 + .DW SN7RATIO / 90579 + .DW SN7RATIO / 91896 + .DW SN7RATIO / 93233 + .DW SN7RATIO / 94589 + .DW SN7RATIO / 95965 + .DW SN7RATIO / 97361 + .DW SN7RATIO / 98777 + .DW SN7RATIO / 100214 + .DW SN7RATIO / 101671 + .DW SN7RATIO / 103150 + .DW SN7RATIO / 104650 + .DW SN7RATIO / 106172 + .DW SN7RATIO / 107716 + .DW SN7RATIO / 109283 + .DW SN7RATIO / 110873 + .DW SN7RATIO / 112486 + .DW SN7RATIO / 114122 + .DW SN7RATIO / 115782 + .DW SN7RATIO / 117466 + .DW SN7RATIO / 119175 + .DW SN7RATIO / 120908 + .DW SN7RATIO / 122667 + .DW SN7RATIO / 124451 + .DW SN7RATIO / 126261 + .DW SN7RATIO / 128098 + .DW SN7RATIO / 129961 + .DW SN7RATIO / 131851 + .DW SN7RATIO / 133769 + .DW SN7RATIO / 135715 + .DW SN7RATIO / 137689 + .DW SN7RATIO / 139691 + .DW SN7RATIO / 141723 + .DW SN7RATIO / 143784 + .DW SN7RATIO / 145876 + .DW SN7RATIO / 147998 + .DW SN7RATIO / 150151 + .DW SN7RATIO / 152335 + .DW SN7RATIO / 154550 + .DW SN7RATIO / 156798 + .DW SN7RATIO / 159079 + .DW SN7RATIO / 161393 + .DW SN7RATIO / 163740 + .DW SN7RATIO / 166122 + .DW SN7RATIO / 168538 + .DW SN7RATIO / 170990 + .DW SN7RATIO / 173477 + .DW SN7RATIO / 176000 + .DW SN7RATIO / 178560 + .DW SN7RATIO / 181157 + .DW SN7RATIO / 183792 + .DW SN7RATIO / 186466 + .DW SN7RATIO / 189178 + .DW SN7RATIO / 191930 + .DW SN7RATIO / 194722 + .DW SN7RATIO / 197553 + .DW SN7RATIO / 200426 + .DW SN7RATIO / 203342 + .DW SN7RATIO / 206299 + .DW C7 SIZ_SN7NOTETBL .EQU $ - SN7NOTETBL .ECHO "SN76489 approx " .ECHO SIZ_SN7NOTETBL / 2 / 4 /12 .ECHO " Octaves. Last note index supported: " - .echo SIZ_SN7NOTETBL / 2 - .echo "\n" + .ECHO SIZ_SN7NOTETBL / 2 + .ECHO "\n" diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 93015bd8..3c2f8af0 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 @@ -20,8 +20,8 @@ ; #INCLUDE "../ver.inc" ; ADD BIOSVER ; -FALSE .EQU 0 -TRUE .EQU ~FALSE +FALSE .EQU 0 +TRUE .EQU ~FALSE ; ; DEBUGGING OPTIONS ; @@ -298,9 +298,9 @@ 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. @@ -457,7 +457,7 @@ 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 @@ -470,11 +470,11 @@ 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 @@ -488,7 +488,7 @@ INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B #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 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/util.asm b/Source/HBIOS/util.asm index f647a5a4..a1ca84ff 100644 --- a/Source/HBIOS/util.asm +++ b/Source/HBIOS/util.asm @@ -183,6 +183,17 @@ PRTHEXWORD: POP AF RET ; +; PRINT THE HEX WORD VALUE IN HL +; +PRTHEXWORDHL: + PUSH AF + LD A,D + CALL PRTHEXBYTE + LD A,E + CALL PRTHEXBYTE + POP AF + RET +; ; PRINT THE HEX DWORD VALUE IN DE:HL ; PRTHEX32: diff --git a/Source/ver.inc b/Source/ver.inc index c6cdf73b..f20047e5 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 1 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1-pre.9" +#DEFINE BIOSVER "3.1-pre.10" diff --git a/Source/ver.lib b/Source/ver.lib index 1524ad08..821e6368 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 1 rup equ 0 rtp equ 0 biosver macro - db "3.1-pre.9" + db "3.1-pre.10" endm From dc2f55570c6b61e99f93dd4b8802cf97538a135e Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Thu, 23 Apr 2020 17:28:18 -0700 Subject: [PATCH 03/18] Make tick frequency configurable --- Source/HBIOS/cfg_dyno.asm | 1 + Source/HBIOS/cfg_ezz80.asm | 1 + Source/HBIOS/cfg_master.asm | 1 + Source/HBIOS/cfg_mk4.asm | 1 + Source/HBIOS/cfg_n8.asm | 1 + Source/HBIOS/cfg_rcz180.asm | 1 + Source/HBIOS/cfg_rcz80.asm | 1 + Source/HBIOS/cfg_sbc.asm | 1 + Source/HBIOS/cfg_scz180.asm | 1 + Source/HBIOS/cfg_zeta.asm | 1 + Source/HBIOS/ctc.asm | 13 +++++++++---- Source/HBIOS/hbios.asm | 22 ++++++++++++++++++---- Source/HBIOS/std.asm | 2 -- Source/ver.inc | 2 +- Source/ver.lib | 2 +- 15 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Source/HBIOS/cfg_dyno.asm b/Source/HBIOS/cfg_dyno.asm index 8226482d..132459e3 100644 --- a/Source/HBIOS/cfg_dyno.asm +++ b/Source/HBIOS/cfg_dyno.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_ezz80.asm b/Source/HBIOS/cfg_ezz80.asm index 990d2e1d..e5425351 100644 --- a/Source/HBIOS/cfg_ezz80.asm +++ b/Source/HBIOS/cfg_ezz80.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm index faafae4e..01b2ee73 100644 --- a/Source/HBIOS/cfg_master.asm +++ b/Source/HBIOS/cfg_master.asm @@ -16,6 +16,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index 8e23bf25..d3bc9127 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index 7cb9a714..6d669358 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_rcz180.asm b/Source/HBIOS/cfg_rcz180.asm index fcdf9d72..ec13c61b 100644 --- a/Source/HBIOS/cfg_rcz180.asm +++ b/Source/HBIOS/cfg_rcz180.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_rcz80.asm b/Source/HBIOS/cfg_rcz80.asm index 02a35956..7896465a 100644 --- a/Source/HBIOS/cfg_rcz80.asm +++ b/Source/HBIOS/cfg_rcz80.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index e682bc01..f834039d 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_scz180.asm b/Source/HBIOS/cfg_scz180.asm index 07d679ce..3f72aefa 100644 --- a/Source/HBIOS/cfg_scz180.asm +++ b/Source/HBIOS/cfg_scz180.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index 93dcb107..13ecfb5d 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -19,6 +19,7 @@ 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 ; diff --git a/Source/HBIOS/ctc.asm b/Source/HBIOS/ctc.asm index 0f056946..a9d80441 100644 --- a/Source/HBIOS/ctc.asm +++ b/Source/HBIOS/ctc.asm @@ -21,19 +21,24 @@ CTC_PREIO .EQU CTCBASE + CTCPRECH CTC_SCLIO .EQU CTCBASE + CTCTIMCH ; #IF (CTCMODE == CTCMODE_CTR) -CTC_DIV .EQU CTCOSC / 50 +CTC_DIV .EQU CTCOSC / TICKFREQ #ENDIF #IF (CTCMODE == CTCMODE_TIM16) -CTC_DIV .EQU CTCOSC / 16 / 50 +CTC_DIV .EQU CTCOSC / 16 / TICKFREQ #ENDIF #IF (CTCMODE == CTCMODE_TIM256) -CTC_DIV .EQU CTCOSC / 256 / 50 +CTC_DIV .EQU CTCOSC / 256 / TICKFREQ #ENDIF ; .ECHO "CTC DIVISOR: " .ECHO CTC_DIV .ECHO "\n" ; +#IF ((CTC_DIV == 0) | (CTC_DIV > $FFFF)) + .ECHO "COMPUTED CTC DIVISOR IS UNUSABLE!\n" + !!! +#ENDIF +; CTC_DIVHI .EQU ((CTC_DIV >> 8) & $FF) CTC_DIVLO .EQU (CTC_DIV & $FF) ; @@ -91,7 +96,7 @@ CTC_PREINIT1: 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. diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 3af09e56..65c4dbff 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1228,6 +1228,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 @@ -2453,7 +2467,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 @@ -2799,9 +2813,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 ; @@ -4179,7 +4193,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 diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 3c2f8af0..32b1739a 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -345,8 +345,6 @@ CPUKHZ .SET CPUKHZ * 2 ; ADJUST FOR DOUBLE SPEED OPERATION ; CPUMHZ .EQU CPUKHZ / 1000 ; CPU FREQ IN MHZ ; -TICKSPERSEC .EQU 50 -; ; MEMORY BANK CONFIGURATION ; #IF (BIOS == BIOS_UNA) diff --git a/Source/ver.inc b/Source/ver.inc index f20047e5..3b64400a 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 1 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1-pre.10" +#DEFINE BIOSVER "3.1-pre.11" diff --git a/Source/ver.lib b/Source/ver.lib index 821e6368..9a135bda 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 1 rup equ 0 rtp equ 0 biosver macro - db "3.1-pre.10" + db "3.1-pre.11" endm From a6aff72d8648989ded1148feaa058f3ba830108f Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Thu, 23 Apr 2020 17:34:17 -0700 Subject: [PATCH 04/18] Update cfg_zeta2.asm Missed Zeta 2 configuration file in last update. --- Source/HBIOS/cfg_zeta2.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/HBIOS/cfg_zeta2.asm b/Source/HBIOS/cfg_zeta2.asm index e42d0503..d93e3e21 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -19,6 +19,7 @@ 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 ; From e654c5739e4f873892b2c112a5aefc69c88b425c Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Thu, 23 Apr 2020 22:08:19 -0700 Subject: [PATCH 05/18] Disk Catalog & Loader Console Command - Disk Catalog document has been added to the Doc directory courtesy of Mykl Orders. - Loader enhanced to allow switching the console device before booting OS or ROM app. --- Doc/ChangeLog.txt | 1 + Doc/RomWBW Applications.pdf | Bin 140215 -> 140215 bytes Doc/RomWBW Architecture.pdf | Bin 396943 -> 396943 bytes Doc/RomWBW Disk Catalog.pdf | Bin 0 -> 130986 bytes Doc/RomWBW Getting Started.pdf | Bin 166220 -> 166329 bytes ReadMe.md | 4 +- ReadMe.txt | 4 +- Source/Doc/Catalog.md | 828 +++++++++++++++++++++++++++++++++ Source/Doc/GettingStarted.md | 5 +- Source/HBIOS/romldr.asm | 167 ++++--- Source/ver.inc | 2 +- Source/ver.lib | 2 +- 12 files changed, 955 insertions(+), 58 deletions(-) create mode 100644 Doc/RomWBW Disk Catalog.pdf create mode 100644 Source/Doc/Catalog.md diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index 50f5f407..c59dbbb3 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -11,6 +11,7 @@ Version 3.1 - WBW: Support TIMER mode in CTC driver - D?N: Added sound driver support - D?N: Added SN76489 sound chip driver +- M?O: RomWBW Disk Catalog document Version 3.0.1 ------------- diff --git a/Doc/RomWBW Applications.pdf b/Doc/RomWBW Applications.pdf index 8bc1135e2ed68689ef93bf92ab3df4f12e39df52..4e1c4b27dd16fe4b5cedfe4a8364293e37aea1a4 100644 GIT binary patch delta 111 zcmdmfoMZcOj)pCa8o$_$jf@P8jLoO(|6-JZakdBjVr12Hc5!lYGd6T}Gjnltax^wF fw=^*|cQUguaB_1sHE=a>wo|Ynq-6RmWhPkw30)nF delta 111 zcmdmfoMZcOj)pCa8o$_$3=IuUObn*$|6-JZakdBjVr12HHZ(GIH8KH0M`I@=Cs#95 eLo-KL7gI-LH)A7HM;9kM1sg(2rq5Dlk_7{#IXT%W*br0_t6*oxRa}x-R8motn#N^pVPt7$$fc_4>hHz{08@`S(*OVf delta 194 zcmeC5E73n!V#AFT0V6|ma|;tAQ{%)mQ)7c9qvjVW+h3$GCU#=Tv`4;U1Y#y2X5Jq8 zj)ngvyOE)xp^1sf^!)3rGBD2eN!MBDnkBe78JIg+IypHT8hHz{08d{yB>(^b diff --git a/Doc/RomWBW Disk Catalog.pdf b/Doc/RomWBW Disk Catalog.pdf new file mode 100644 index 0000000000000000000000000000000000000000..72d259f0d3432f33d687760bc376fc0a80276d23 GIT binary patch literal 130986 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

eT!oK%se9QY=0{1_X#Xq6d@9-@zbe0T` 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 literal 0 HcmV?d00001 diff --git a/Doc/RomWBW Getting Started.pdf b/Doc/RomWBW Getting Started.pdf index 99f132330355482b09020140ded9efafc6749e35..e25d7453e537ce1ba29491d3b5a354fba1746ed3 100644 GIT binary patch delta 14751 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 delta 14616 zcmai4d0da#_g5&=WQmYa6d`){Ws*seu~xQ3p;VSEAt|Z{*|TIxiHeaBvX^c04P}U8 z?1ikA$;eXH8o%=t)#o0s*YERJo!340oO|wB-sjxs)F!>F8}%YbM88ed>aIK-J=7`R zuGydOdwe+AC+L1$W!VwCh`nQ7`gSsRZraOj`2HMYPs5AnN)P;L#;^X{c~x@R@ymJd z%L}iyo6B_FZc_TTV7u<7KP#J#ZuaoC*^Ktv3$-NKbshjU(=OtCQik+sc{n$3$6|Q80q=Xi}p*rjwf1W^F`J+ zBV8&sJj~I(^ZBCXoTw(@TDLzLS&dlM{%+{4i+^{pf4G?q@cFmI_wyI&m4R-@&a(?k z7=ytDW!AQ(Md{b(=)O~|zI|@f_7`YtjO0rmzZu&w4ZK~8EpF|W7=C+^P+;x z#;HvT28|B8eYD(l>8=$YXWX?C8tcv3(4_mVE*rL`Iu&>g81=QYL6TO{-s`!?+WNWg zj5%^L(Sj-&-s95Ru;1=~ZCrfOGJ2ECWy53dw6B;&J8#pnQby$u&!?J&=DHT&h~Kx& zd|Z0jzEgICZS=W;*)8*QpRIhHafCfu|3bn1d4s2QS+-?-{MoU7u9I_9)-@X2X~`pl zm6huX!^3wi?HoJNF?ea=-IW_#W;V|3<})STF8a}Nx488=m9yS|^z~bM!P0kHkG_4| zJTo7BH7jDXiTm}<9_Z!sZ{g`Pxw{V!wEUyxkt-Q;fS>?&#K~H-DojtkI2#vBx9aw>IsvnSS3s zWp_vC*HKaBhK>QfELY6Fn(Ef+>DEtUW8$(J-gxtJX1{}f=s4^5YY`B!z1(wAFQxpy zg?rupU3kp>h0n4G-`$-}J}=K{Z`fe&W4_S{lP*RV6W?mR4E5kYKb<{&eg9Zboxc`Z zh54-cxFk%Qzp~Pgx!Cnl;&hwAH==S^roBuJm2T>{ys~hcb>^lQ4GeCsZ#cAn)O@ce zN0+Vk8g$meMAz2u+qkt3ZVxucS)N{d{8}8BsrXv_lM;O`^!D`P=7axxbFch#_Xzjq zdH>xEH`qP$Y@tW`o&jgF)Bkm8P;hJfr<*or^L~3hXy>I_1t%<|!R2p9_Hb-;G}63n z?4iKb%@0%McUm|~%SSdTPWkY>uzs4S$Esm5qxQG7pK*2fd#SSC*Sx0t?*28t!q%I+ z6PN21+SBZ8OXXqs+w(`7?YXwCaL|UGD?V#2UpT?GY=zeto#d>TZb^rxJv-)<(Q4)T zxQX?T@=Yw~9qIPKdT#8Iz759O_|`LC-obRP)5vRM>4Ojcmo>=q!7U%x)gR^^@;h_6 z;PTB`zbr5IX0^TAF7u83by4L|-49xsqL)( zJ+J<9xVv(&<1+V$^Yc@V_Da5He|FKdCQ~=xO-sI<@=Pyw%s%>|?XL%^>@!FGi>8^c z4frf!(WZ=I!qs zbLT|xux@7Y+liqyHQ0iSY?nkFH62 z{n(mbf6`<7_MG7zRs@#MY%!p@()_?a|4Fx_77RLAJaTRDm5GS5*0Lkma*4HH&PeR_bU(YJGn--5U4Budxw!u=%v15In=QeFHvsB_- z2hYuy^wU4O2F)rP^2f$oUt^@9+aC4_eERD7_1BA|V#bUZSXO+4`xd69J!eMOnP>lu z(QdRPD5RdJd?w-Y{e0Jrci(SwJ!E||DCuvz{Zj112iG=V^&ObJWXQ|=L*=hlIjc`? zc{;A7u)9&y6Fp1Y%+FO6| z3X^8`4de9`N0Y#ml|IIu#)-{#?LC+gklC*N@;Qqhm%KW*@7{;51M9cy|9pLJK{5(cO_39xE;l`;{7(jQy&+*Cm6d*X}4YOx0@TIQCxHjEF0@ z9(CK1k+5`i<8D@6+#_X*4pd zNw)O%WrSA#sACR!9r`;NEM9nK!KC&&TZdfkJZQdg;}Kzp^wuA*x1euK#QZ+T>C>Ll z0>$)p3q#}ax80tWPvQ?-y=ZjtPRZ%+SDoc8y41r-Hv&FQijBV*l6W>XYHE|OUb+qQ zeN5~Y7G{N~`L1fS@LR^+`p@$Cw4${4+<*y@Z`a+>igqyk>(sfKdcCqU6SLFI$M_Yc zyS(aK+CKiRti435pVy=M1>R<+Jp=Y^7~1!l!E-MqJI-=&xOvf%8AEOxq?T`3blBYF zT7!APO>efWZ{zBno#!iTQ`1+KyFWc}&Lp^LA&80c>!l{ zpN=*j*x*EmJ#CfyZZ_1hT{G*Q?B{J4eSCMR&bEOQlit~tOxJnQs(8qao8S7E1P%D- zRK3ibnP&RU2lkE#Xi?ldG%rf)^R1|TIVV4KJ`ftzJ8S5T@@EUy7DptuS^3^Da!mgo zDe0N-{xJ+4+I7bo-KWmIQkO=zzBnc(rNZY^7i({$DKo<@KJMMO#;cq1VafbtZ_^7c z?^s37UJz1N_UMFXuliAMPnIPmdf66z%|H66UZ3a{of_#bSYjLE67kob`*y=8_-yIu z?Htl0#CFx}W0y0_?FYANZ+L{dz4-6m76<*<2T$gf7N43G*7oqLPm3=5f6J5fyw8vM z)=pn%_)Xq#i>AOFELd8`5lW7wD#BaD^xMAZ772B_mH0bl6kuW*Isqb%wd~w;c8v+RGrseCUxVQZTlP-Obr0UYGh%j8Qq$|b z*D47%E-!AqHpsscYGzp4V?mp+W}jnkZ`EG&J|W<6a`sT&p3}d%Z-3EbqVI)opMxA@ zb9OH5mXSsknht91nthJB{2=G`)+TqOC(&hR9zT9!lpb`l^3Ry@>A#Ijk7)BIWZC^w z^FQY0C;L*p(sb6XbFi)G{=2o$$I9}|+q_d+v)!H7C{NBcyI&Mv#xQP+RBa~an=?w-e)6^`sq?Jid~ewn#1=Es%m>G&j%nU8C#w-aA-ypc?}}a zIF>@pEG5a&pFFg?D##d&ED<_^xkVo7&QdI4a9GDn#5$nK3~39RVdU>Bu{B1c8IC44 zq-cg`NZn~By19?Gp~8sh(rAfd2>BGl&@3q*Bq31@$4I2J0EHoGtg0uNSgGr2EHBEM zmqAgiC{v^|6vqkVI*Jo$d}pG7E{2oq9!`}HKb{iNhCIWd4S7~1PeSoLvJAxw65dZ@ z@qUVo%tZ+_N1B=v7@2SLa_Rm#BmYZr3zUewS^&F}RuCYilBO0|Mk19KSQa^_8_gyG0=SJdK&Pt1tu?r5+esUR()N=?yF zV31${9*CEbfL5LVYGRw_BoyyJLunLBv`A(+T7)uBSP+zv$s9n7a&7unzJoj(QUGFx ztc;jt9>E|Qt`pt6EMQ-d1@ek%1@ab3w*WTK9W%5{VFe|GLKy&vM0nCP4_S(^46IWR zTxI_n^D`Wa!j54jd%K~xcfA?EAm*Xm2)7yu&VLf}O-ibt-+8}K!e^0MYtgG zXn-ifI7IavHRfuPE;N%Unnf0_l@tuqI#NMU27wWg#n=G~McwjNm2)YPheAUNQ8On= z18*X&1ydcAoT0O230{aP4Dm!!knmtAIn1RDL_i)=U5JKK5;zJL%%da?EiaizU_T9*Tophdm_rj!Scs4U)D_%eK^PFq zfDl}PBuOS4SCFePXc!5ui0Y;!qk$GM)7Y$l(@?a?ESc1R7ot~P>~_lkYETlO&Tx*yws$@fLG%sMD;DGt5n@0 zrIJ+M?>VD3R$yHfl<5QuYSK6qWfE)wbF^m|1PeSMk!b=hOXEP*vhbJ~)}bm6p-<*Y z5XGV3hgXiOTdf-`a7Z+p0%jHsOkf=vDM0^E1{(0@F zXw@E3Cs=?PLkbz18ss0eKqgL=m&FQ-2%yT)xYkXas{MhPN0A2E0gaqwS|+<6;N?(4 zgcn(a`+-IV8t}3T3VVn>vIKx5pb0K8!(dU<{IE`Ae4<{7O2fGd8r*8D)~WXJvVd|G z&~W4m)K3)r$u%(o+3C<6FKdD_)&4LRM^FK(D_Piq82|}7F$^zB8W;iPIcTFvfDW%5 zf>JkgR+)=s>c*!^0>J`VXCPqVct|ija%<9nm&aiT-OP7oYC2rl5KSzA8HO*K8^St) zjCY{H08n$C%8U9V=n4t!4E6^iIg~Mh@ zhVq&xfjI<=DzK~$1T@zHFBAk#8t?*qLNs{9{7$QRW|9HXp>X19eD6Gm6A~|=c>v5x zQR@N)ot%)hhKV3b!9a_?5dy^#I#T3g0&eYP5oY1!A>oMzB}9=&Gc3qxIH*LpSJ+Pt z&e|dlJrS}loRRQ5s8E1qNM)evAzpA=bkl%Z>hP-a!9SsmCWO%NB@THDKm(W86bv-Y zbPwAB?I-)uP!~vETH$N_k4@ z=7(2M7-ge{A~_(1b@=-tN}Ym}yf6hP{2eA;l19c>?GKN}G#0``pG0oR1I!|6>KqW! z;O!jIaH*gKS;1Pv5WJ3qfPSE$2p{Q?8^W6gQV_a-#H&8!lf2L}Ra>jJIKoG57(1(| z2%QeR8kto_18;a@m&v*XU(Ug|X?2wW`vVc*6C9Zw*TNhRK18d_tn$+6gAkxWZ;RG_ z|LCWVzroWvtB_`eS2zs^QO!@oH*rL4gIur;DTIYIj%YZV;2WnO;HjoKs$V1`tf@jT z($p}vArlSM6PUG=f}sK+1!20X871%y0LKD5$qZu_Op}qb(h^irf*0n5WC{jj{iJnZ zKxtz9t4=3=e4bL17ofhOfz?BD^McW~$@J4lYQ sgQJ5z)SN!1z5m}O9;SWz=*)DU<{&%&a=lcV1M0nJRV?*IS* diff --git a/ReadMe.md b/ReadMe.md index 0ef34b7f..bbd5b46e 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -3,7 +3,7 @@ ## Z80/Z180 System Software Version 3.1 Pre-release -Wednesday 22 April 2020 +Thursday 23 April 2020 Wayne Warthen @@ -1144,8 +1144,10 @@ applications are no longer provided. - 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 4337d2cb..27ad0aa6 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -3,7 +3,7 @@ RomWBW Z80/Z180 System Software Version 3.1 Pre-release -Wednesday 22 April 2020 +Thursday 23 April 2020 Wayne Warthen wwarthen@gmail.com @@ -1176,8 +1176,10 @@ applications are no longer provided. - 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/Source/Doc/Catalog.md b/Source/Doc/Catalog.md new file mode 100644 index 00000000..eabf792f --- /dev/null +++ b/Source/Doc/Catalog.md @@ -0,0 +1,828 @@ +!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` | -- | | +| `UNARC.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 4148a245..dada3943 100644 --- a/Source/Doc/GettingStarted.md +++ b/Source/Doc/GettingStarted.md @@ -1197,8 +1197,10 @@ list of general code enhancements. * 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. @@ -1211,6 +1213,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). \ No newline at end of file diff --git a/Source/HBIOS/romldr.asm b/Source/HBIOS/romldr.asm index 9cf31c0c..833dac77 100644 --- a/Source/HBIOS/romldr.asm +++ b/Source/HBIOS/romldr.asm @@ -146,7 +146,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. @@ -281,6 +281,10 @@ 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 'C' ; C = set console unit + jp z,setcon ; if so, do it +#endif ; ; Attempt ROM application launch ld ix,(ra_tbl_loc) ; point to start of ROM app tbl @@ -334,7 +338,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,6 +426,46 @@ devlst: call pstr ; display it jp prtall ; do it ; +; Set console unit +; +#if (BIOS == BIOS_WBW) +; +setcon: + ; On entry DE is expected to be pointing to start + ; of command + 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 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 + jp nc,err_nocon ; handle invalid unit +; + ; Notify user, we're outta here.... + push af ; save new console unit + ld hl,str_newcon ; new console msg + call pstr ; print string on cur console + pop af ; 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 + ret ; done +; +#endif +; ; Restart system ; reboot: @@ -433,7 +477,7 @@ reboot: ; #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 @@ -465,7 +509,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 +553,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 +593,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 @@ -574,7 +618,7 @@ diskboot: ; #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) @@ -616,7 +660,7 @@ diskboot1: 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 b,BF_DIOSEEK ; HBIOS func: seek ld a,(bootunit) ; get boot disk unit ld c,a ; put in C rst 08 ; do it @@ -627,7 +671,7 @@ diskboot1: 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 hl,bl_infosec ; read into info sec buffer ld d,BID_USR ; user bank ld e,1 ; transfer one sector rst 08 ; do it @@ -752,7 +796,7 @@ diskboot5: ld b,BF_DIOREAD ; HBIOS func: read sectors ld a,(bootunit) ; get boot disk unit ld c,a ; put in C - ld hl,(bb_cpmloc) ; load address + 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 @@ -827,7 +871,7 @@ diskboot6: ; #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 @@ -947,6 +991,16 @@ 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 + 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. ; @@ -956,7 +1010,6 @@ skipws: ret nz ; nope, done inc de ; bump buffer pointer jr skipws ; and loop - ; ; Uppercase character in A ; @@ -1186,7 +1239,7 @@ prtall1: 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 @@ -1349,6 +1402,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 +1434,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",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 @@ -1408,12 +1466,12 @@ acmd_to .dw BOOT_TIMEOUT ; auto cmd timeout ;======================================================================= ; str_banner .db PLATFORM_NAME," Boot Loader",0 -;str_prompt .db "Boot [(H)elp]: ",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_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 @@ -1427,10 +1485,13 @@ str_binfo4 .db ", entry @ 0x",0 str_binfo5 .db "]",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 C - Set Console Unit" +#endif + .db "\r\n [.] - Boot Disk Unit/Slice" .db 0 ; #if (DSKYENABLE) @@ -1448,34 +1509,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 +1577,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 diff --git a/Source/ver.inc b/Source/ver.inc index 3b64400a..311c55f8 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 1 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1-pre.11" +#DEFINE BIOSVER "3.1-pre.12" diff --git a/Source/ver.lib b/Source/ver.lib index 9a135bda..f5cc5c1c 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 1 rup equ 0 rtp equ 0 biosver macro - db "3.1-pre.11" + db "3.1-pre.12" endm From 8b7c167592a21057fe64130813a1e4808892bdf3 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Fri, 24 Apr 2020 11:33:15 -0700 Subject: [PATCH 06/18] Cleanup loader console assignment --- Source/CBIOS/cbios.asm | 42 ++++++++++++++++++++++++++--------------- Source/HBIOS/romldr.asm | 12 +++++++++--- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/Source/CBIOS/cbios.asm b/Source/CBIOS/cbios.asm index 47c2ca47..f861e737 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -2045,7 +2045,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 +2054,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 diff --git a/Source/HBIOS/romldr.asm b/Source/HBIOS/romldr.asm index 833dac77..884c5cce 100644 --- a/Source/HBIOS/romldr.asm +++ b/Source/HBIOS/romldr.asm @@ -282,7 +282,7 @@ runcmd: cp 'R' ; R = reboot system jp z,reboot ; if so, do it #if (BIOS == BIOS_WBW) - cp 'C' ; C = set console unit + cp 'I' ; C = set console interface jp z,setcon ; if so, do it #endif ; @@ -426,7 +426,7 @@ devlst: call pstr ; display it jp prtall ; do it ; -; Set console unit +; Set console interface unit ; #if (BIOS == BIOS_WBW) ; @@ -462,6 +462,12 @@ setcon: 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 @@ -1489,7 +1495,7 @@ str_help .db "\r\n" .db "\r\n D - Disk Device Inventory" .db "\r\n R - Reboot System" #if (BIOS == BIOS_WBW) - .db "\r\n C - Set Console Unit" + .db "\r\n I - Set Console Interface" #endif .db "\r\n [.] - Boot Disk Unit/Slice" .db 0 From 7d6b0113623a4f88f83f831e37802b650f3aaf9e Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Thu, 23 Apr 2020 18:39:49 +1000 Subject: [PATCH 07/18] Whitespace: adjusted whitespace for tms.asm --- Source/HBIOS/tms.asm | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index 832e99e0..35497a64 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -107,7 +107,7 @@ TMS_INIT1: ; XOR A ; SIGNAL SUCCESS RET -; +; ;====================================================================== ; TMS DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS ;====================================================================== @@ -170,19 +170,19 @@ 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 XOR A ; SIGNAL SUCCESS RET - + TMS_VDASCS: CALL PANIC ; NOT IMPLEMENTED (YET) - + TMS_VDASCP: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO @@ -192,15 +192,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 @@ -211,7 +211,7 @@ TMS_VDAWRC: CALL TMS_SETCUR XOR A ; SIGNAL SUCCESS RET - + TMS_VDAFIL: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO @@ -239,7 +239,7 @@ TMS_VDACPY: CALL TMS_SETCUR XOR A RET - + TMS_VDASCR: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO @@ -294,7 +294,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 @@ -398,7 +398,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 @@ -597,7 +597,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 @@ -733,7 +733,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: From ff2ebbb09f168651d0078df7401956e71344cc08 Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Thu, 23 Apr 2020 18:43:16 +1000 Subject: [PATCH 08/18] TMS: Enable support for using VSYNC interrupt Use the VSYNC interrupt to trigger the sys timer event --- Source/HBIOS/cfg_master.asm | 1 + Source/HBIOS/cfg_mk4.asm | 1 + Source/HBIOS/cfg_n8.asm | 1 + Source/HBIOS/cfg_sbc.asm | 1 + Source/HBIOS/hbios.asm | 4 +++ Source/HBIOS/std.asm | 1 + Source/HBIOS/tms.asm | 61 +++++++++++++++++++++++++++++++++++++ 7 files changed, 70 insertions(+) diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm index 01b2ee73..c5ad1178 100644 --- a/Source/HBIOS/cfg_master.asm +++ b/Source/HBIOS/cfg_master.asm @@ -152,6 +152,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) VGASIZ .EQU V80X25 ; VGA: DISPLAY FORMAT [V80X25|V80X30|V80X43] ; diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index d3bc9127..0b247c57 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -107,6 +107,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) VGASIZ .EQU V80X25 ; VGA: DISPLAY FORMAT [V80X25|V80X30|V80X43] ; diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index 6d669358..20f54fb2 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -110,6 +110,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) VGASIZ .EQU V80X25 ; VGA: DISPLAY FORMAT [V80X25|V80X30|V80X43] ; diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index f834039d..0e751225 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -111,6 +111,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) VGASIZ .EQU V80X25 ; VGA: DISPLAY FORMAT [V80X25|V80X30|V80X43] ; diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 65c4dbff..cc7fda0c 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -986,6 +986,10 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK ; ; MAKE SURE IM1 INT VECTOR IS RIGHT #IF (INTMODE == 1) + #IF (TMSTIMENABLE) + CALL TMS_INT_DIS ; SPECIAL CASE - NEED TO STOP TMS9918 FROM FIRING INTERRUPTS + #ENDIF ; WHEN DRIVER IS LOADED - IT WILL BE RELOADED + ; JP INT_IM1 IF INTERRUPT MODE ACTIVE LD A,$C3 LD ($0038),A diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 32b1739a..15dfdb34 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -186,6 +186,7 @@ AYMODE_RCZ180 .EQU 4 ; RC2014 SOUND MODULE BY ED BRINDLEY ON Z180 TMSMODE_NONE .EQU 0 TMSMODE_SCG .EQU 1 ; SCG ECB BOARD TMSMODE_N8 .EQU 2 ; N8 BUILT-IN VIDEO +TMSMODE_RC2014 .EQU 3 ; RC2014 BUILT-IN VIDEO ; ; SERIAL DEVICE CONFIGURATION CONSTANTS ; diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index 35497a64..e6c05c0c 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" +#ENDIF + +#IF (TMSMODE == TMSMODE_RC2014) +TMS_DATREG .EQU $BE ; READ/WRITE DATA +TMS_CMDREG .EQU $BF ; 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 @@ -93,6 +111,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,6 +136,23 @@ TMS_INIT1: ; XOR A ; SIGNAL SUCCESS RET + +#IFDEF APPBOOT +#IF TMSTIMENABLE + ; SPECIAL CASE FOR APPBOOT - NEEDING TO DISABLE INTERRUPT GENERATOR + ; ISSUE: + ; IF THE CURRENT ROMBOOT HAD LOADED THE TMS DRIVER + ; THEN THE ROMLOADER MAY START RECEIVING INTERRUPTS + ; FROM THE CHIP BEFORE THE TMS DRIVER HAS BEEN RE- + ; INITALISED, AND CAUSING BAD INT PANICS +TMS_INT_DIS: + 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 +#ENDIF +#ENDIF ; ;====================================================================== ; TMS DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS @@ -745,6 +791,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 @@ -798,6 +858,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 From 9957fbfd33e13b2c42e82bd4213560c3804f7d07 Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Fri, 24 Apr 2020 18:19:12 +1000 Subject: [PATCH 09/18] ChangeLog: Whitespace and updated D?N to DEN --- Doc/ChangeLog.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index c59dbbb3..d9cbbacd 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -9,8 +9,8 @@ Version 3.1 - 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 -- D?N: Added sound driver support -- D?N: Added SN76489 sound chip driver +- DEN: Added sound driver support +- DEN: Added SN76489 sound chip driver - M?O: RomWBW Disk Catalog document Version 3.0.1 @@ -283,7 +283,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 @@ -315,7 +315,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 @@ -325,8 +325,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) @@ -354,7 +354,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 @@ -373,7 +373,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 From ef52d1730313fd0e6dacd6c046b91f00f8128e33 Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Fri, 24 Apr 2020 18:21:04 +1000 Subject: [PATCH 10/18] ChangeLog: Added entries for TMS/SYSTIME --- Doc/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index d9cbbacd..c2b35af5 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -12,6 +12,7 @@ Version 3.1 - 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) Version 3.0.1 ------------- From 1388b8495c88616b4bd6f82fb0eb5a20a15d3ae4 Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Sat, 25 Apr 2020 12:30:51 +1000 Subject: [PATCH 11/18] whitespace: removed trailing whitespaces from Tune.asm --- Source/Apps/Tune/Tune.asm | 102 +++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/Source/Apps/Tune/Tune.asm b/Source/Apps/Tune/Tune.asm index 046b83ac..60ef8d38 100644 --- a/Source/Apps/Tune/Tune.asm +++ b/Source/Apps/Tune/Tune.asm @@ -51,9 +51,9 @@ ; 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 ; @@ -75,8 +75,8 @@ TYPMYM .EQU 3 ; FILTYP value for MYM sound file CALL CRLF LD DE,MSGBAN ; Point to banner message CALL PRTSTR ; Print message -; - ; Check BIOS and version +; + ; Check BIOS and version CALL IDBIO ; Identify hardware BIOS CP 1 ; RomWBW HBIOS? JP NZ,ERRBIO ; If not, handle BIOS error @@ -111,7 +111,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 @@ -142,15 +142,15 @@ MAT: LD C,$D0 ; TIMER subfunction RST 08 ; DE:HL := current tick count LD A,L ; DE:HL == 0? - OR H - OR E - OR D + 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: +SETDLY: LD (WMOD),A ; Save wait mode CALL PRTSTR ; Print it ; @@ -170,7 +170,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 +179,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 @@ -220,7 +220,7 @@ _LD0 LD C,15 ; CPM Open File function 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,19 +240,19 @@ _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 +; + ; Play loop CALL CRLF2 ; Formatting LD DE,MSGPLY ; Playing message CALL PRTSTR ; Print message @@ -319,7 +319,7 @@ waitvb call WAITQ ld (played),a ;call PRTDOT jr mymlp -; +; EXIT CALL START+8 ; Mute audio ;CALL NORMCPU ;CALL CRLF2 ; Formatting @@ -330,14 +330,14 @@ EXIT CALL START+8 ; Mute audio ; ; 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 +; 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 +; + ; Timer loop CALL TIM2 ; Read timer LSB into A LD C,A ; Init prev value TIM1 PUSH BC ; Save prev value @@ -346,13 +346,13 @@ TIM1 PUSH BC ; Save 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] @@ -410,7 +410,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 ; @@ -530,7 +530,7 @@ PRTSTR1: ; PRTSTR2: POP DE ; restore registers - RET + RET ; ; Print the value in A in hex without destroying any registers ; @@ -553,7 +553,7 @@ PRTHEXWORD: LD A,B CALL PRTHEX LD A,C - CALL PRTHEX + CALL PRTHEX POP AF RET ; @@ -590,9 +590,9 @@ HEXASCII: HEXCONV: AND $0F ; low nibble only ADD A,$90 - DAA + DAA ADC A,$40 - DAA + DAA RET ; ; Print value of A or HL in decimal with leading zero suppression @@ -712,28 +712,28 @@ 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, $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, $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, $D1, $D0, $D0, $FF, $FF ; EZZ80 W/ RC SOUND MODULE (EB) .DW HWSTR_RCMF @@ -765,10 +765,10 @@ 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 MSGUSE .DB "Copyright (C) 2020, Wayne Warthen, GNU GPL v3",13,10 .DB "PTxPlayer Copyright (C) 2004-2007 S.V.Bulba",13,10 @@ -843,7 +843,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) @@ -1128,7 +1128,7 @@ TP_2 LD A,H #IF CurPosCounter LD (CurPos),A #ENDIF - + #ENDIF LD HL,VARS @@ -1441,7 +1441,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 +1660,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 +1783,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 @@ -2137,7 +2137,7 @@ ABC LD HL,AYREGS LOUT OUT (C),A LD B,E - OUTI + OUTI LD B,D INC A CP 13 @@ -2158,7 +2158,7 @@ LOUT OUT (C),A LD HL,AYREGS LOUT OUT (C),A INC C - OUTI + OUTI DEC C INC A CP 13 @@ -2197,7 +2197,7 @@ LOUT2 EI RET ; And done #ENDIF - + #IF ACBBAC CHTABLE .EQU $-4 .DB 4,5,15,%001001,0,7,7,%100100 @@ -2518,7 +2518,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 @@ -2593,7 +2593,7 @@ notrig: ld hl,(psource) ld (played),a endint: call NORMIO - ei + ei ret ; And done ; ; *** Program data From d156aba1f9b6d9feed0aa3bc2a42da3c98e237ca Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Sat, 25 Apr 2020 16:57:54 +1000 Subject: [PATCH 12/18] tune.com: Updated to support using HBIOS sound driver A new command line switch has been added '--hbios'. Using this switch after the filename, will cause tune.com to play thru the HBIOS sound driver MYM file types are not supported thru HBIOS yet. --- Source/Apps/Tune/Build.cmd | 6 +- Source/Apps/Tune/Makefile | 14 +- Source/Apps/Tune/Tune.asm | 516 +++++++++++++--------------------- Source/Apps/Tune/cli.inc | 33 +++ Source/Apps/Tune/cpm.inc | 4 + Source/Apps/Tune/hbios.inc | 15 + Source/Apps/Tune/printing.inc | 175 ++++++++++++ Source/Apps/Tune/strings.inc | 39 +++ Source/Apps/Tune/timing.inc | 60 ++++ Source/Apps/Tune/tune.inc | 4 + Tools/Makefile.inc | 20 +- 11 files changed, 551 insertions(+), 335 deletions(-) create mode 100644 Source/Apps/Tune/cli.inc create mode 100644 Source/Apps/Tune/cpm.inc create mode 100644 Source/Apps/Tune/hbios.inc create mode 100644 Source/Apps/Tune/printing.inc create mode 100644 Source/Apps/Tune/strings.inc create mode 100644 Source/Apps/Tune/timing.inc create mode 100644 Source/Apps/Tune/tune.inc diff --git a/Source/Apps/Tune/Build.cmd b/Source/Apps/Tune/Build.cmd index 568f73dc..45186edc 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 Tune.lst +tasm -t180 -g3 -fFF -dMSX Tune.asm Tunemsx.com Tune.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..cbca69a5 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 + +Tunezx.com: $(DEPS) + $(TASM) -dZX Tune.asm Tunezx.com + +Tunemsx.com: $(DEPS) + $(TASM) -dMSX Tune.asm Tunemsx.com all:: mkdir -p $(DEST)/Tunes diff --git a/Source/Apps/Tune/Tune.asm b/Source/Apps/Tune/Tune.asm index 60ef8d38..f669387b 100644 --- a/Source/Apps/Tune/Tune.asm +++ b/Source/Apps/Tune/Tune.asm @@ -39,6 +39,7 @@ ; 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 ;_______________________________________________________________________________ ; ; ToDo: @@ -49,43 +50,65 @@ ; 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 ; 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 ; -; -; + +;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 +FAIL +#ELSE +#IFDEF MSX +_MSX .SET 1 +FAIL +#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 -; + PRTCRLF + PRTSTRDE(MSGBAN) ; Print to banner message + + CALL CLI_ABRT_IF_OPT_FIRST + CALL CLI_HAVE_HBIOS_SWITCH + 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 @@ -137,21 +160,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 @@ -214,6 +225,8 @@ 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 @@ -327,43 +340,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 ; @@ -482,190 +464,7 @@ NORMIO: 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 - RET + ; ERRBIO: ; Invalid BIOS or version LD DE,MSGBIO @@ -767,13 +566,15 @@ 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 +HBIOSOPT: .DB "--HBIOS", 0 +HBIOSMD .DB 0 ; NON-ZERO IF USING HBIOS SOUND DRIVER, ZERO OTHERWISE + +MSGBAN .DB "Tune Player for RomWBW v3.1, 25-Apr-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]",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 +586,14 @@ 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_RCMF .DB "RC2014 Sound Module (MF)",0 + +MSGUNSUP .db "MYM FILES NOT SUPPORTED YET\r\n", 0 ; ;=============================================================================== ; PTx Player Routines @@ -799,23 +603,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 ;-------- @@ -2130,7 +1917,7 @@ RxCA2 OR E ABC #ENDIF -#IF ZX +#IF _ZX XOR A LD DE,$FFBF LD BC,$FFFD @@ -2151,7 +1938,7 @@ LOUT OUT (C),A RET #ENDIF -#IF MSX +#IF _MSX ;MSX version of ROUT (c)Dioniso XOR A LD C,$A0 @@ -2172,30 +1959,111 @@ 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 + 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 NORMIO EI - RET ; And done + RET ; AND DONE + +PLAYVIAHBIOS: + LD B, BF_SNDVOL + LD C, 0 + LD H, 0 + LD A, (AYREGS + AmplA) + AND $0F + rlca + rlca + rlca + rlca + LD L, A + RST 08 + + LD B, BF_SNDPIT + LD C, 0 + LD HL, (AYREGS+TonA) + ld a, h + AND $3F + LD H, A + RST 08 + + LD B, BF_SNDPLAY + LD C, 0 + LD D, 0 + RST 08 + + LD B, BF_SNDVOL + LD C, 0 + LD H, 0 + LD A, (AYREGS + AmplB) + AND $0F + rlca + rlca + rlca + rlca + LD L, A + RST 08 + + LD B, BF_SNDPIT + LD C, 0 + LD HL, (AYREGS+TonB) + ld a, h + AND $3F + LD H, A + RST 08 + + LD B, BF_SNDPLAY + LD C, 0 + LD D, 1 + RST 08 + + LD B, BF_SNDVOL + LD C, 0 + LD H, 0 + LD A, (AYREGS + AmplC) + AND $0F + rlca + rlca + rlca + rlca + LD L, A + RST 08 + + LD B, BF_SNDPIT + LD C, 0 + LD HL, (AYREGS+TonC) + ld a, h + AND $3F + LD H, A + RST 08 + + LD B, BF_SNDPLAY + LD C, 0 + LD D, 2 + RST 08 + + RET #ENDIF #IF ACBBAC @@ -2553,9 +2421,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 +2438,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 @@ -2596,6 +2471,7 @@ endint: call NORMIO 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..c8ac9b8c --- /dev/null +++ b/Source/Apps/Tune/cli.inc @@ -0,0 +1,33 @@ + + +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 COMNMAND LINE + LD DE, HBIOSOPT + CALL STRINDEX + JR NZ, CLI_HAVE_HBIOS_SWITCH1 + OR $FF ; IS NOT HBIOS + LD (HBIOSMD), A + RET +CLI_HAVE_HBIOS_SWITCH1: + AND 0 ; IS HBIOS + 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 \ No newline at end of file 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..874a9699 --- /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 - D IS CHANNEL, E CONTAINS VOLUME (255 MAX, 0 SILENT) - SCALED AS REQUIRED BY DRIVER (EG: MAPS TO JUST 4 BIT RESOLUTION FOR SN76489) +BF_SNDPIT .EQU BF_SND + 2 ; REQUEST SOUND PITCH - D IS CHANNEL, HL CONTAINS PITCH (0 LOWEST NOTE, FFFF HIGHEST NOTE) - SCALED BY DRIVER (EG: MAPS TO JUST 10 BITS FOR SN76489 ) +BF_SNDPLAY .EQU BF_SND + 4 ; INITIATE THE REQUESTED SOUND COMMAND +BF_SNDQUERY .EQU BF_SND + 5 ; D IS CHANNEL, E IS SUBCOMMAND diff --git a/Source/Apps/Tune/printing.inc b/Source/Apps/Tune/printing.inc new file mode 100644 index 00000000..8a6b4e9a --- /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 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 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/Tools/Makefile.inc b/Tools/Makefile.inc index 0de5bc5e..bccb2e26 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 @@ -67,7 +67,7 @@ CPM=$(TOOLS)/cpm/bin %.com: %.z80 $(ZXCC) $(CPM)/Z80ASM -$(basename $<)/F ; \ mv $$($(CASEFN) $@) tmp.com ; mv tmp.com $@ - + %.bin: %.asm $(TASM) $< $@ @@ -77,10 +77,10 @@ CPM=$(TOOLS)/cpm/bin %.rel: %.z80 $(ZXCC) $(CPM)/Z80ASM -$(basename $<)/MF -%.hex: %.180 +%.hex: %.180 $(ZXCC) $(CPM)/SLR180 -$(basename $<)/HF -%.rel: %.azm +%.rel: %.azm $(ZXCC) $(CPM)/ZSM =$< %.bin: %.rel @@ -143,7 +143,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 @@ -166,8 +166,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 From 0381c72ca257c7743288db095dfa75de715b4c7e Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Sat, 25 Apr 2020 22:23:30 +1000 Subject: [PATCH 13/18] Fix issue with TMS interrupt support - some default configurations were missing --- Source/HBIOS/cfg_dyno.asm | 1 + Source/HBIOS/cfg_ezz80.asm | 1 + Source/HBIOS/cfg_rcz180.asm | 1 + Source/HBIOS/cfg_rcz80.asm | 1 + Source/HBIOS/cfg_scz180.asm | 1 + Source/HBIOS/cfg_zeta.asm | 1 + Source/HBIOS/cfg_zeta2.asm | 1 + 7 files changed, 7 insertions(+) diff --git a/Source/HBIOS/cfg_dyno.asm b/Source/HBIOS/cfg_dyno.asm index 132459e3..1322676b 100644 --- a/Source/HBIOS/cfg_dyno.asm +++ b/Source/HBIOS/cfg_dyno.asm @@ -90,6 +90,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; 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 e5425351..99e94ced 100644 --- a/Source/HBIOS/cfg_ezz80.asm +++ b/Source/HBIOS/cfg_ezz80.asm @@ -115,6 +115,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; 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 ec13c61b..6a2b259d 100644 --- a/Source/HBIOS/cfg_rcz180.asm +++ b/Source/HBIOS/cfg_rcz180.asm @@ -118,6 +118,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; 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 7896465a..7682f2b7 100644 --- a/Source/HBIOS/cfg_rcz80.asm +++ b/Source/HBIOS/cfg_rcz80.asm @@ -124,6 +124,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; 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 3f72aefa..24abe9f0 100644 --- a/Source/HBIOS/cfg_scz180.asm +++ b/Source/HBIOS/cfg_scz180.asm @@ -113,6 +113,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index 13ecfb5d..865f2506 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -88,6 +88,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; 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 d93e3e21..0109f702 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -98,6 +98,7 @@ 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: INTERRUPTS NOT ENABLED VGAENABLE .EQU FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) ; SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM) From c3e78ec8f5a8415bba0b74bd22c75d448e299a46 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Sat, 25 Apr 2020 10:48:35 -0700 Subject: [PATCH 14/18] Minor Cleanup --- Source/Apps/Tune/Build.cmd | 4 ++-- Source/HBIOS/hbios.asm | 8 ++++---- Source/HBIOS/std.asm | 2 +- Source/HBIOS/tms.asm | 9 ++++++++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Source/Apps/Tune/Build.cmd b/Source/Apps/Tune/Build.cmd index 45186edc..82fa4c33 100644 --- a/Source/Apps/Tune/Build.cmd +++ b/Source/Apps/Tune/Build.cmd @@ -6,8 +6,8 @@ set PATH=%TOOLS%\tasm32;%PATH% set TASMTABS=%TOOLS%\tasm32 tasm -t180 -g3 -fFF -dWBW Tune.asm Tune.com Tune.lst -tasm -t180 -g3 -fFF -dZX Tune.asm Tunezx.com Tune.lst -tasm -t180 -g3 -fFF -dMSX Tune.asm Tunemsx.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 diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index cc7fda0c..1120cebe 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -986,10 +986,6 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK ; ; MAKE SURE IM1 INT VECTOR IS RIGHT #IF (INTMODE == 1) - #IF (TMSTIMENABLE) - CALL TMS_INT_DIS ; SPECIAL CASE - NEED TO STOP TMS9918 FROM FIRING INTERRUPTS - #ENDIF ; WHEN DRIVER IS LOADED - IT WILL BE RELOADED - ; JP INT_IM1 IF INTERRUPT MODE ACTIVE LD A,$C3 LD ($0038),A @@ -1259,6 +1255,10 @@ HB_CPU2: ; #ENDIF ; +#IF (TMSENABLE) + CALL TMS_PREINIT +#ENDIF +; ; INITIALIZE HEAP STORAGE ; ; INITIALIZE POINTERS diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 15dfdb34..cbd8f0a3 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -186,7 +186,7 @@ AYMODE_RCZ180 .EQU 4 ; RC2014 SOUND MODULE BY ED BRINDLEY ON Z180 TMSMODE_NONE .EQU 0 TMSMODE_SCG .EQU 1 ; SCG ECB BOARD TMSMODE_N8 .EQU 2 ; N8 BUILT-IN VIDEO -TMSMODE_RC2014 .EQU 3 ; RC2014 BUILT-IN VIDEO +TMSMODE_RC .EQU 3 ; RC2014 BUILT-IN VIDEO ; ; SERIAL DEVICE CONFIGURATION CONSTANTS ; diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index e6c05c0c..14c50b3d 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -22,7 +22,7 @@ TMSINTEN: .EQU 5 ; INTERRUPT ENABLE BIT .ECHO "TMS INTERRUPTS ENABLED" #ENDIF -#IF (TMSMODE == TMSMODE_RC2014) +#IF (TMSMODE == TMSMODE_RC) TMS_DATREG .EQU $BE ; READ/WRITE DATA TMS_CMDREG .EQU $BF ; READ STATUS / WRITE REG SEL TMS_PPIA .EQU 0 ; PPI PORT A @@ -80,6 +80,13 @@ TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER ; TMS DRIVER - INITIALIZATION ;====================================================================== ; +TMS_PREINIT: +#IF (TMSTIMENABLE) + CALL TMS_INT_DIS ; SPECIAL CASE - NEED TO STOP TMS9918 FROM FIRING INTERRUPTS +#ENDIF ; WHEN DRIVER IS LOADED - IT WILL BE RELOADED + + RET +; TMS_INIT: #IF (CPUFAM == CPU_Z180) CALL TMS_Z180IO From 6d9172f635b20414258671c873094241578ee731 Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Sun, 26 Apr 2020 10:27:19 +1000 Subject: [PATCH 15/18] Replace FAIL with git statusgit status! to force assembler to error --- Source/HBIOS/cvdu.asm | 2 +- Source/HBIOS/sn76489.asm | 2 +- Source/HBIOS/tms.asm | 2 +- Source/HBIOS/vdu.asm | 2 +- Source/HBIOS/vga.asm | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/HBIOS/cvdu.asm b/Source/HBIOS/cvdu.asm index 4b51dfa2..1ceb847d 100644 --- a/Source/HBIOS/cvdu.asm +++ b/Source/HBIOS/cvdu.asm @@ -96,7 +96,7 @@ CVDU_FNTBL: .DW KBD_READ #IF (($ - CVDU_FNTBL) != (VDA_FNCNT * 2)) .ECHO "*** INVALID CVDU FUNCTION TABLE ***\n" - FAIL + !!!!! #ENDIF CVDU_VDAINI: diff --git a/Source/HBIOS/sn76489.asm b/Source/HBIOS/sn76489.asm index 18f7f649..3c12acb6 100644 --- a/Source/HBIOS/sn76489.asm +++ b/Source/HBIOS/sn76489.asm @@ -304,7 +304,7 @@ SN7_FNTBL: #IF (($ - SN7_FNTBL) != (SND_FNCNT * 2)) .ECHO "*** INVALID SND FUNCTION TABLE ***\n" - FAIL + !!!!! #ENDIF PENDING_PITCH diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index 14c50b3d..b802d569 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -189,7 +189,7 @@ TMS_FNTBL: #ENDIF #IF (($ - TMS_FNTBL) != (VDA_FNCNT * 2)) .ECHO "*** INVALID TMS FUNCTION TABLE ***\n" - FAIL + !!!!! #ENDIF TMS_VDAINI: diff --git a/Source/HBIOS/vdu.asm b/Source/HBIOS/vdu.asm index 1c2a2ca1..2c057ca2 100644 --- a/Source/HBIOS/vdu.asm +++ b/Source/HBIOS/vdu.asm @@ -150,7 +150,7 @@ VDU_FNTBL: .DW PPK_READ #IF (($ - VDU_FNTBL) != (VDA_FNCNT * 2)) .ECHO "*** INVALID VDU FUNCTION TABLE ***\n" - FAIL + !!!!! #ENDIF VDU_VDAINI: diff --git a/Source/HBIOS/vga.asm b/Source/HBIOS/vga.asm index dde15dae..30bb2b4e 100644 --- a/Source/HBIOS/vga.asm +++ b/Source/HBIOS/vga.asm @@ -163,7 +163,7 @@ VGA_FNTBL: .DW KBD_READ #IF (($ - VGA_FNTBL) != (VDA_FNCNT * 2)) .ECHO "*** INVALID VGA FUNCTION TABLE ***\n" - FAIL + !!!!! #ENDIF VGA_VDAINI: From f7748cc6db8e933603561ad82ca1cebf0ae32768 Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Sun, 26 Apr 2020 10:28:01 +1000 Subject: [PATCH 16/18] Tune.asm - removed typo 'FAIL' labels --- Source/Apps/Tune/Tune.asm | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Apps/Tune/Tune.asm b/Source/Apps/Tune/Tune.asm index f669387b..aa28cb95 100644 --- a/Source/Apps/Tune/Tune.asm +++ b/Source/Apps/Tune/Tune.asm @@ -68,11 +68,9 @@ _WBW .EQU 0 HBIOS .EQU 0 #IFDEF ZX _ZX .SET 1 -FAIL #ELSE #IFDEF MSX _MSX .SET 1 -FAIL #ELSE _WBW .SET 1 From 392e729d57e025357853d32491b3071b901c50cd Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Sun, 26 Apr 2020 10:48:34 +1000 Subject: [PATCH 17/18] tms: Correctly implemented pre-init to disable interrupts --- Source/HBIOS/hbios.asm | 6 +++--- Source/HBIOS/tms.asm | 26 ++++++++------------------ 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 1120cebe..865e2005 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1255,9 +1255,6 @@ HB_CPU2: ; #ENDIF ; -#IF (TMSENABLE) - CALL TMS_PREINIT -#ENDIF ; ; INITIALIZE HEAP STORAGE ; @@ -1658,6 +1655,9 @@ HB_PCINITTBL: #IF (UFENABLE) .DW UF_PREINIT #ENDIF +#IF (TMSENABLE) + .DW TMS_PREINIT +#ENDIF HB_PCINITTBLLEN .EQU (($ - HB_PCINITTBL) / 2) ;================================================================================================== diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index b802d569..fb594f93 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -81,11 +81,12 @@ TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER ;====================================================================== ; TMS_PREINIT: -#IF (TMSTIMENABLE) - CALL TMS_INT_DIS ; SPECIAL CASE - NEED TO STOP TMS9918 FROM FIRING INTERRUPTS -#ENDIF ; WHEN DRIVER IS LOADED - IT WILL BE RELOADED - - RET + ; 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) @@ -144,21 +145,10 @@ TMS_INIT1: XOR A ; SIGNAL SUCCESS RET -#IFDEF APPBOOT #IF TMSTIMENABLE - ; SPECIAL CASE FOR APPBOOT - NEEDING TO DISABLE INTERRUPT GENERATOR - ; ISSUE: - ; IF THE CURRENT ROMBOOT HAD LOADED THE TMS DRIVER - ; THEN THE ROMLOADER MAY START RECEIVING INTERRUPTS - ; FROM THE CHIP BEFORE THE TMS DRIVER HAS BEEN RE- - ; INITALISED, AND CAUSING BAD INT PANICS + ; DISABLE INTERRUPT TMS_INT_DIS: - 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 -#ENDIF + #ENDIF ; ;====================================================================== From 072f0f7562846b5ae7189149e25cbdedca5d4406 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Sat, 25 Apr 2020 19:42:43 -0700 Subject: [PATCH 18/18] Updated KERMIT applications with VT100 terminal support Provided by Jim McGinnis. --- Doc/ChangeLog.txt | 1 + .../u0/KERMIT.COM => d_cpm22/u0/KERCPM22.COM} | Bin 29440 -> 29696 bytes .../u0/KERMIT.COM => d_cpm3/u0/KERCPM3.COM} | Bin 29440 -> 29440 bytes .../d_nzcom/u0/{KERMIT.COM => KERCPM22.COM} | Bin 29440 -> 29696 bytes .../u0/KERMIT.COM => d_zpm3/u15/kercpm3.com} | Bin 29312 -> 29440 bytes .../kermit.com => d_zsdos/u0/KERCPM22.COM} | Bin 29312 -> 29696 bytes 6 files changed, 1 insertion(+) rename Source/Images/{d_zsdos/u0/KERMIT.COM => d_cpm22/u0/KERCPM22.COM} (95%) rename Source/Images/{d_cpm22/u0/KERMIT.COM => d_cpm3/u0/KERCPM3.COM} (96%) rename Source/Images/d_nzcom/u0/{KERMIT.COM => KERCPM22.COM} (95%) rename Source/Images/{d_cpm3/u0/KERMIT.COM => d_zpm3/u15/kercpm3.com} (96%) rename Source/Images/{d_zpm3/u15/kermit.com => d_zsdos/u0/KERCPM22.COM} (95%) diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index c2b35af5..3b10f0a5 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -13,6 +13,7 @@ Version 3.1 - 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 Version 3.0.1 ------------- diff --git a/Source/Images/d_zsdos/u0/KERMIT.COM b/Source/Images/d_cpm22/u0/KERCPM22.COM similarity index 95% rename from Source/Images/d_zsdos/u0/KERMIT.COM rename to Source/Images/d_cpm22/u0/KERCPM22.COM index b24df273d412a4a4428797ea2b9e4814a94acf0d..a3a9f3c29823c1df0aeb7436256ad281e7b33b3b 100644 GIT binary patch delta 859 zcmYk4Ur19?9LLXfv$pBPsX?`xw|0m^vbkR5no=%QG);6WWkF`wTIqJrIaf2wZT3*~ zAQYnqUwr5fg7i=rEa=Joki3H%jWFn;Y=mJFMUVL)o#UVAp5LDj=llD?{oVVEf0N?N z(sOGh_Jqz-xXoaa!8C&z2KN|DFu2bk#o#pqgoG_JSYYsu!4d-tg+&7I3A`a-5?Chi zo4_i8XBvFw5``}mvJ}2jSf=ok!moAn6R_)WmVl2!DQ(mde`?tuD@BDUaW_(abc_|` zo4IJzzoNNns98!~L%N79>wHkKxrgq%qwjyL)g1Rf)yz+c<;bbZa-n3nd%DdDw%ODn znv`)ZIqw=5XecY%ns4<1QO==cdVo{|O*Ct}bK@j8HInGpcEzTMrK@c8W%?Bv*_(Pq zGQ}`SGNB8~wD!R=f2cY&OAM*R%4d*Daz)JFX4-WZ)%h@zw4F12B$8y?1e<*e@-{%c zOS+JkI-!_HA-lq&*;PfC7Ul|Kc0T)TCTnE9Uhns4k+(Q+_(jS`4W|S5M#6oe%Y#(C zB=<$AjOFVg{fdmwI~`6(%izF8mCBJmS?lS&rs_=j|Bk9U4XNU;F4V8e;hq6i!J^IS zXcP5Za5~xrNlIc(3lx>nn}#?>)E{Tws6WOM?W8p}z$~r7HmosAFn9(tX6Xo2;31yc zD)0@F{P-5@$U&V}gmO?<4!UYZQ7f``K2+k&Z$XAKww}x)lAJep5TnW5NsOgACB{yR zxwFPU#hhlz)C@CB58-Akm_O(gPQPVMrki98kBu*8bAVA>)gk<3)!YM<7Pg1a1lKlO*flXmUV9vOab0I z+~(Dm*KBXj!LBOb{YW1gR-Wi)*l6aD`ySXyU8u|Y-_Rcf^(-sbPQoCK8(Dq3I|=T} z8RNF@8@UC}$-e2?+C8||Te$)C%~XPV=Dhk`|Kh9$1}hIi_$8~lUotJ)YcF9AytCZ; zt@mw%Ye)+R4iu@H54mROp%)urd?2?NWUCcFcS6x8G$%MMt60;l1RdWl7F>@P;r4MQY zPgyH^|6Qynrkj^59xhBjSP=8(C_a^I0X}B-SWEG5STAHd@2hqXtCO*U{$A8ct<$$*feks%sM0vRbO3r6u|QXe4^z#Qtzd?&=&bB(admU6g{s YpnNXT)oH!OqRG@{RkG8zGawoM2d%*pPyhe` diff --git a/Source/Images/d_cpm22/u0/KERMIT.COM b/Source/Images/d_cpm3/u0/KERCPM3.COM similarity index 96% rename from Source/Images/d_cpm22/u0/KERMIT.COM rename to Source/Images/d_cpm3/u0/KERCPM3.COM index b24df273d412a4a4428797ea2b9e4814a94acf0d..4882ea5098768f03320d5486c0781f1daa25109b 100644 GIT binary patch delta 861 zcmYjPUr19?7{8ZoxozZvmFX5pEiG-Pk}M_5f)!}|Gj z6|~o&2a%+Lih|K&_e0nn++vgkJyeS{w4$=N1nZnFp>w}KKfZtGyWe-Fm-y)={-HUZ zn8g}~pBQ)o4gwVfRxzw$_=UksKqA0#j9Lja5%3Y{AYjJu0l_N-X#~#^EF)M&u!i8i z3h${4Lk`1744*J8WB88YN1k>e7$Fcw;KLx{dxR?-Gsl&3$t&^Np|7g5*syT^FRHVI z>M8$3T-DF63S3iDY4JLPdSFFeZ~T1|1x|9Q zOboRENru!a%VlKICX=ITWnvDQj&GlOl6i_QR%smAo>AcHK zC&0TbOqLWGBSd^jCyaT%m|}Q~c;5OCSZy1?Q2?x$j7UQTa8b$J;tQ56Hsi&Gd1t~# zC-y9x({nX7HOrSa)s#6dJkoqv7wmE*9vhCHnZU}BG#tm0ES-;zpOxfOf?cp5o)|l= zU@1Ne*x;BFkXf2wKf>avL$LQT#0Qe=YA~?_PwMPr z$64h0Lz|+S$;El6nYEbH^Gi;pohD{B93-Vx5dDF^V0^=OG7ZFOq4uoqvC>EAk?2bD zNSw+4>@6mPy(jwHkL_&h3rW(}raDRT`RjWk<)Li!-oXB%_bM1EV#qn6jN%We1LM0a=R?khq}QuRCb4Cj;2yy Zx7?}36da96!QO^Y{q9B@mVDe<{ui!qN;v=k delta 760 zcmYk4T}TvB6vwYSyBX3hO_H^#%c!GdlIc9zm?EtpWgoJxN)*wyJH(bBbI#p@3SFUx zdgvh-dgvjDLW(HrL0IS^Y7fa?V}gY&SnVN5iG1y$ddOy0+q(B~{y*-y_rU$%JH1ji zy;AnvJCR<48l+E1KaqT#0-U}eeMeeFs^wJ0i7_{HPHmi8IQ4MKz(za*dRpWcK(BzF zn6w{BN9sg6fYgl?MmmIaxELBxf>S3@0Z0HVj=LE3BHOxVU7u)*ubP2!+sCve3~X_9 zQu}7gU%?h2-{NlmQDnnqdk*Syy#9gN-J{Kzb_WW!r;N!G3)WXcQL5G@xGpsyhn!l- zlFc1Wjo{BVKv%X7#DaX!ZI>7NH}iMfF9iJ*%gi5xE*iAP%w4`1__8Ohn`W^021p|< zle6=8;7V=w8ssY}4f*65{jvE$$~AXo?}G>_j&C8wc2cA3;2g-a+_|d!vY3~_QXuFl zfYk}r)(jj>FThpdPBEn|V#AbHK;f?lN1{r?xRi_={)&NUq{Pwai4qTm+y8Oof7UkE z)lHJqNX?<-^ibcTqwIOQYSaLizs-!NPhQf_eBc3u6 wiu!kJcwpbry&Y|;zhW>I!&GwooYLCbs-7P5S2$~tfmr;4uDI0=vLM#+2ag6bA^-pY diff --git a/Source/Images/d_nzcom/u0/KERMIT.COM b/Source/Images/d_nzcom/u0/KERCPM22.COM similarity index 95% rename from Source/Images/d_nzcom/u0/KERMIT.COM rename to Source/Images/d_nzcom/u0/KERCPM22.COM index b24df273d412a4a4428797ea2b9e4814a94acf0d..a3a9f3c29823c1df0aeb7436256ad281e7b33b3b 100644 GIT binary patch delta 859 zcmYk4Ur19?9LLXfv$pBPsX?`xw|0m^vbkR5no=%QG);6WWkF`wTIqJrIaf2wZT3*~ zAQYnqUwr5fg7i=rEa=Joki3H%jWFn;Y=mJFMUVL)o#UVAp5LDj=llD?{oVVEf0N?N z(sOGh_Jqz-xXoaa!8C&z2KN|DFu2bk#o#pqgoG_JSYYsu!4d-tg+&7I3A`a-5?Chi zo4_i8XBvFw5``}mvJ}2jSf=ok!moAn6R_)WmVl2!DQ(mde`?tuD@BDUaW_(abc_|` zo4IJzzoNNns98!~L%N79>wHkKxrgq%qwjyL)g1Rf)yz+c<;bbZa-n3nd%DdDw%ODn znv`)ZIqw=5XecY%ns4<1QO==cdVo{|O*Ct}bK@j8HInGpcEzTMrK@c8W%?Bv*_(Pq zGQ}`SGNB8~wD!R=f2cY&OAM*R%4d*Daz)JFX4-WZ)%h@zw4F12B$8y?1e<*e@-{%c zOS+JkI-!_HA-lq&*;PfC7Ul|Kc0T)TCTnE9Uhns4k+(Q+_(jS`4W|S5M#6oe%Y#(C zB=<$AjOFVg{fdmwI~`6(%izF8mCBJmS?lS&rs_=j|Bk9U4XNU;F4V8e;hq6i!J^IS zXcP5Za5~xrNlIc(3lx>nn}#?>)E{Tws6WOM?W8p}z$~r7HmosAFn9(tX6Xo2;31yc zD)0@F{P-5@$U&V}gmO?<4!UYZQ7f``K2+k&Z$XAKww}x)lAJep5TnW5NsOgACB{yR zxwFPU#hhlz)C@CB58-Akm_O(gPQPVMrki98kBu*8bAVA>)gk<3)!YM<7Pg1a1lKlO*flXmUV9vOab0I z+~(Dm*KBXj!LBOb{YW1gR-Wi)*l6aD`ySXyU8u|Y-_Rcf^(-sbPQoCK8(Dq3I|=T} z8RNF@8@UC}$-e2?+C8||Te$)C%~XPV=Dhk`|Kh9$1}hIi_$8~lUotJ)YcF9AytCZ; zt@mw%Ye)+R4iu@H54mROp%)urd?2?NWUCcFcS6x8G$%MMt60;l1RdWl7F>@P;r4MQY zPgyH^|6Qynrkj^59xhBjSP=8(C_a^I0X}B-SWEG5STAHd@2hqXtCO*U{$A8ct<$$*feks%sM0vRbO3r6u|QXe4^z#Qtzd?&=&bB(admU6g{s YpnNXT)oH!OqRG@{RkG8zGawoM2d%*pPyhe` diff --git a/Source/Images/d_cpm3/u0/KERMIT.COM b/Source/Images/d_zpm3/u15/kercpm3.com similarity index 96% rename from Source/Images/d_cpm3/u0/KERMIT.COM rename to Source/Images/d_zpm3/u15/kercpm3.com index 16dc23085851059630100f964b06bb9bdd006371..4882ea5098768f03320d5486c0781f1daa25109b 100644 GIT binary patch delta 718 zcmYk4PiPZS5XN_HqRGZBt_@fX4QsO~qSC~Il(p4rOIs|hqEZi0u*R)!ZIgZTS`#P2>27Qk)ldb5O}mx+)gn;v5TS)@EySy1akzR5-by3Ah<~I zu7z(|3$O_I9`FNT8Soq6_ewMq9Hy8gm;hAa4i&1)CkU$q`*KF#xC=ZLlvkA3eHFgK z*=vCHpJ?NxwX=QOl;yp#KWF+{uJcZTWi;t6E|~_nNxy2%=9Ft3UHyyoJO1ki(T@nT z`7~)mYWG{~{FjK|Id6|zYqK+?=J4hVkMfVnxdvyF6zcF6DVWFf+t$mP+@?0iA+8wq zvAM;tpVyVkyd z^9xT3MYkA>#mW~~$Ld07A2h@qwjM-5%$Hd#8r^{gRF2RVtl{m1H9wgv1?5^oOC zS*M=5_uP5!D@^B`Xsw@(S8$^N_8+1uyXOiila&+Pp-k3I??*YH}pm%b3M(mU~!suNRvoYU5x?l84=JSkOso_SOvj($v>6EyCgDJ$?oW9=uh6S{L;R_J5S>y zv~E%rTDb-BhurS}>kl{9LG?1@TrblN8!-=Wg6o!I{Lpo$>mA?>+O)vZWCInci?}YNiJuv#;D}e=v`DNq@skmEV~z7E@b>H z5>K#%goRu&ooD40Sz?Nmm$GGPk@>DyBeM@<4;}@54*Og=jpbbN4GRPUzWG-UyYUvE PO=sVV%uIX4A)UMez4_6o diff --git a/Source/Images/d_zpm3/u15/kermit.com b/Source/Images/d_zsdos/u0/KERCPM22.COM similarity index 95% rename from Source/Images/d_zpm3/u15/kermit.com rename to Source/Images/d_zsdos/u0/KERCPM22.COM index 16dc23085851059630100f964b06bb9bdd006371..a3a9f3c29823c1df0aeb7436256ad281e7b33b3b 100644 GIT binary patch delta 996 zcmYk5L2MI86hLRQ4v7sLv4lc{!P&%9REi4Dp3u^u5(7a*gvdCFN{U2kHekT<&dich zD6!!H;(!FQIOLK8w2Bn<(27by;uL>H%|_a)Ruv=;lv>DAN~NF82Aj97`$Zgn!yha{DCeGe{v{uc*bFg!@nF}RK;Wvbm16-7>8DV$R+r7iB|zm z){?^Y?AFxZPE&(lPs}T#X${)T=5t5i!~IsSkGXQ}t@6i`{ms1Xn%jQQ+4H&iz2iUO z9{EHex=LEwn_1OtsF{|U+066^`XUA0*|`5BrWK>Cv)IPGMSX`{u7nyH@+ZXdPW^Hx z>!vd^uiupDSLN&_-HW{T3d42{9Ju(}5F zEDLKfRD)(5rCT4B$@*?yS)6Oi1+ieWrLtF!Mx%d?uZuRXzVK5q#yu@WQ`ymx^r`dQ zK52|(xj~Ju)9z`59@j!zsP}y4E1MhH5yKfyowZ$Iy+6lom#1wxcOZSvHb#dtwnb%{ z7D~u?bZDWYk`$}(pA*k*=a)SBd*fzaM90mXzyrh+N#mqFmQLAPs4tmV;biiQ74DCB zyyL|CY%b5!RVpq-GeX5Rs3TNNr$VThNypG6I_Nh!X-)dA=&vIK0Yd7?U>!LVAmafN z7`S8Qg{czHx>7a%IyN)!f55yR|3l_g=B%7JB5PRoRy_W+m?_>Do*!W--lG2xpIZ1; z^!Q;`@*<7+NFoN_nJVdB*o_8khipn=ibZmBdbhk<<;uCO#BWq0yD_v}!-JSQknD)X zX!x`6(82J~AuSXP(i&1NJk*1XvKO@rHIBNEQhYCO6+>zGFeR9Zz8>0bkJ>z)GU9zZ O4}ZEVhG7LUeBpn5r*yRd delta 599 zcmX|7O=uHQ5PmUwWh&VRB<>(bp#x6PdEqiUPJ6E$2|NFW(*?RmcZ0tpZN;T>5DLB zyUz`2yRsp+7VP56tP~JDvut}eY0XQ1x9p5#%QDdZXfHSy@J;(MNv+(z~$