From 890dd1cd5effee29e22cf83a7b1167353c0f5fb1 Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Wed, 24 Jul 2024 14:33:14 +1000 Subject: [PATCH] eZ80: added support for sn76489 driver --- Source/HBIOS/Config/RCEZ80_std.asm | 4 +- Source/HBIOS/Config/RCZ80_std.asm | 6 +-- Source/HBIOS/cfg_rcez80.asm | 5 +- Source/HBIOS/ez80instr.inc | 43 ++++++++++++++-- Source/HBIOS/hbios.asm | 7 +++ Source/HBIOS/sn76489.asm | 80 ++++++++++++++++++++++++------ 6 files changed, 120 insertions(+), 25 deletions(-) diff --git a/Source/HBIOS/Config/RCEZ80_std.asm b/Source/HBIOS/Config/RCEZ80_std.asm index 9426400f..a5245967 100644 --- a/Source/HBIOS/Config/RCEZ80_std.asm +++ b/Source/HBIOS/Config/RCEZ80_std.asm @@ -53,7 +53,7 @@ VDAEMU_SERKBD .SET 0 ; VDA EMULATION: SERIAL KBD UNIT #, OR $FF FOR HW KBD ; AY38910ENABLE .SET FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER AYMODE .SET AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC] -SN76489ENABLE .SET FALSE ; SN: ENABLE SN76489 SOUND DRIVER +SN76489ENABLE .SET TRUE ; SN: ENABLE SN76489 SOUND DRIVER ; FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPFDC] @@ -67,5 +67,5 @@ IMMENABLE .SET FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) -EZ80_IO_FREQ .SET 8000 +EZ80_IO_FREQ .SET 5250 EZ80_MEM_FREQ .SET 8000 diff --git a/Source/HBIOS/Config/RCZ80_std.asm b/Source/HBIOS/Config/RCZ80_std.asm index 13689758..964a5ad5 100644 --- a/Source/HBIOS/Config/RCZ80_std.asm +++ b/Source/HBIOS/Config/RCZ80_std.asm @@ -50,9 +50,9 @@ VRCENABLE .SET FALSE ; VRC: ENABLE VGARC VIDEO/KBD DRIVER (VRC.ASM) EFENABLE .SET FALSE ; EF: ENABLE EF9345 VIDEO DRIVER (EF.ASM) VDAEMU_SERKBD .SET 0 ; VDA EMULATION: SERIAL KBD UNIT #, OR $FF FOR HW KBD ; -AY38910ENABLE .SET FALSE ; AY: AY-3-8910 / YM2149 SOUND DRIVER -AYMODE .SET AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC] -SN76489ENABLE .SET FALSE ; SN: ENABLE SN76489 SOUND DRIVER +AY38910ENABLE .SET TRUE ; AY: AY-3-8910 / YM2149 SOUND DRIVER +AYMODE .SET AYMODE_MSX ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC] +SN76489ENABLE .SET TRUE ; SN: ENABLE SN76489 SOUND DRIVER ; FDENABLE .SET TRUE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPFDC] diff --git a/Source/HBIOS/cfg_rcez80.asm b/Source/HBIOS/cfg_rcez80.asm index df4b903c..2b124873 100644 --- a/Source/HBIOS/cfg_rcez80.asm +++ b/Source/HBIOS/cfg_rcez80.asm @@ -47,12 +47,13 @@ MPGENA .EQU $7C ; Z2 MEM MGR PAGING ENABLE REGISTER (BIT 0, WRITE ONLY) ; BUS TIMING FOR PAGED MEMORY ACCESS (CS3) EZ80_MEM_CYCLES .EQU 3 ; EZ80 CYCLES FOR MEMORY (1-15) EZ80_MEM_FREQ .EQU 8000 ; CALCULATE APPROPRIATE BUS CYCLES TO ACHIVE APPOX BUS FREQUENCY -EZ80_MEM_ASSIGN .EQU 0 ; 0 -> USE FREQ, 1 -> USE CYCLES ; ; BUS TIMING FOR EXTERNAL I/O ACCESS (CS2) EZ80_IO_CYCLES .EQU 3 ; EZ80 CYCLES FOR IO (1-15) EZ80_IO_FREQ .EQU 8000 ; CALCULATE APPROPRIATE BUS CYCLES TO ACHIVE APPOX BUS FREQUENCY -EZ80_IO_ASSIGN .EQU 0 ; 0 -> USE FREQ, 1 -> USE CYCLES +; +; SELECT CYCLES, OR CALCULATE CYCLES BASED ON DESIRED FREQUENCY +EZ80_ASSIGN .EQU 0 ; 0 -> USE FREQ, 1 -> USE CYCLES ; RTCIO .EQU $C0 ; RTC LATCH REGISTER ADR ; diff --git a/Source/HBIOS/ez80instr.inc b/Source/HBIOS/ez80instr.inc index f64043d4..35037033 100644 --- a/Source/HBIOS/ez80instr.inc +++ b/Source/HBIOS/ez80instr.inc @@ -7,9 +7,12 @@ ; EMIT PREFIX REQUIRED BY EZ80 TO ENSURE CORRECT 16 BIT IO OPERATION ; #IF (CPUFAM == CPU_EZ80) - #DEFINE EZ80_IO .DB $49, $CF ; RST.L $08 - #DEFINE EZ80_FN .DB $49, $D7 ; RST.L $10 - #DEFINE EZ80_BNKSEL .DB $49, $DF ; RST.L $18 + ; RST.L $08 + #DEFINE EZ80_IO .DB $49, $CF + ; RST.L $10 + #DEFINE EZ80_FN .DB $49, $D7 + ; RST.L $18 + #DEFINE EZ80_BNKSEL .DB $49, $DF #DEFINE EZ80_UTIL_VER_EXCH XOR A \ LD B, 0 \ EZ80_FN #DEFINE EZ80_UTIL_EHL_TO_HL XOR A \ LD B, 1 \ EZ80_FN @@ -18,6 +21,7 @@ #DEFINE EZ80_UTIL_SET_BUSFQ XOR A \ LD B, 4 \ EZ80_FN #DEFINE EZ80_UTIL_GET_CPU_FQ XOR A \ LD B, 5 \ EZ80_FN #DEFINE EZ80_UTIL_BNK_HLP XOR A \ LD B, 6 \ EZ80_FN + #DEFINE EZ80_UTIL_DEBUG XOR A \ LD B, 7 \ EZ80_FN #DEFINE EZ80_RTC_INIT LD A, 1 \ LD B, 0 \ EZ80_FN #DEFINE EZ80_RTC_GET_TIME LD A, 1 \ LD B, 1 \ EZ80_FN @@ -29,6 +33,33 @@ #DEFINE EZ80_TMR_SET_SECONDS LD A, 2 \ LD B, 3 \ EZ80_FN #DEFINE EZ80_TMR_GET_FREQTICK LD A, 2 \ LD B, 4 \ EZ80_FN #DEFINE EZ80_TMR_SET_FREQTICK LD A, 2 \ LD B, 5 \ EZ80_FN + #DEFINE EZ80_TMR_DELAY_START LD A, 2 \ LD B, 6 \ EZ80_FN + #DEFINE EZ80_TMR_DELAY_WAIT LD A, 2 \ LD B, 7 \ EZ80_FN + + #DEFINE EZ80_DELAY_START(p,store) \ + #DEFCONT \ PUSH AF + #DEFCONT \ PUSH BC + #DEFCONT \ PUSH HL + #DEFCONT \ LD A, 2 + #DEFCONT \ LD BC, (6 * 256) + p + #DEFCONT \ EZ80_FN + #DEFCONT \ LD (store), HL + #DEFCONT \ POP HL + #DEFCONT \ POP BC + #DEFCONT \ POP AF + + #DEFINE EZ80_DELAY_WAIT(p,store) \ + #DEFCONT \ PUSH AF + #DEFCONT \ PUSH BC + #DEFCONT \ PUSH HL + #DEFCONT \ LD A, 2 + #DEFCONT \ LD BC, (7 * 256) + p + #DEFCONT \ LD HL, (store) + #DEFCONT \ EZ80_FN + #DEFCONT \ LD (store), HL + #DEFCONT \ POP HL + #DEFCONT \ POP BC + #DEFCONT \ POP AF #DEFINE EZ80_UART_IN LD A, 3 \ LD B, 0 \ EZ80_FN #DEFINE EZ80_UART_OUT LD A, 3 \ LD B, 1 \ EZ80_FN @@ -74,4 +105,10 @@ IO_SEGMENT .EQU $FF ; THE UPPER 8-BIT ADDRESS FOR I/O #ELSE #DEFINE EZ80_IO + + #DEFINE EZ80_DELAY_START(p,store) + #DEFINE EZ80_DELAY_WAIT(p,store) + +IO_SEGMENT .EQU $FF ; THE UPPER 8-BIT ADDRESS FOR I/O + #ENDIF diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index f5d27a33..5e9285d1 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -2162,9 +2162,16 @@ HB_CLRIVT_Z: LD (CB_CPUKHZ), HL LD (HB_CPUOSC), HL +#IF (EZ80_ASSIGN == 1) + + LD H, EZ80_MEM_CYCLES + LD L, EZ80_IO_CYCLES + EZ80_UTIL_SET_BUSTM() +#ELSE LD HL, EZ80_MEM_FREQ LD DE, EZ80_IO_FREQ EZ80_UTIL_SET_BUSFQ() ; H -> CS3 CYCLES, L -> CS2 CYCLES +#ENDIF LD A, H LD (EZ80_PLT_C3CYL), A LD A, L diff --git a/Source/HBIOS/sn76489.asm b/Source/HBIOS/sn76489.asm index 6f31de33..9b5770b5 100644 --- a/Source/HBIOS/sn76489.asm +++ b/Source/HBIOS/sn76489.asm @@ -4,7 +4,7 @@ ; WRITTEN BY: DEAN NETHERTON ;====================================================================== ; -; SN74489 PSG CHIP NEEDS AN INPUT CLOCK FREQUENCY OF +; SN76489 PSG CHIP NEEDS AN INPUT CLOCK FREQUENCY OF ; NO MORE THAN 4 MHZ. THE CLOSEST THING THERE IS TO A STANDARD ; IS THE MSX FREQ OF 3.579545 MHZ. ; @@ -37,6 +37,20 @@ SN76489_PORT_RIGHT .EQU $BF ; PORTS FOR ACCESSING THE SN76489 CHIP (RIGHT) DEVECHO "RC" #ENDIF ; + +SN76489_PORT16_LEFT .EQU (IO_SEGMENT*256) + SN76489_PORT_LEFT +SN76489_PORT16_RIGHT .EQU (IO_SEGMENT*256) + SN76489_PORT_RIGHT + +#IF (CPUFAM == CPU_EZ80) +; The eZ80 configuration must have sufficient bus cycles configured for this driver +; to work. See the entries: (EZ80_ASSIGN and EZ80_IO_CYCLES or EZ80_IO_FREQ) +; +; For CPU @ ~18Mhz, the eZ80 must have at least 4 Bus Cycles for I/O operations +; For CPU @ ~24Mhz, the eZ80 must have at least 5 Bus Cycles for I/O operations + +SN76489_IO_DELAY .EQU 15 ; 200us DELAY BETWEEN CHANNEL WRITES + +#ENDIF DEVECHO ", IO_LEFT=" DEVECHO SN76489_PORT_LEFT DEVECHO ", IO_RIGHT=" @@ -102,21 +116,34 @@ SN7_VOLUME_OFF: OUT (RTCIO),A ; TO HALF CLOCK SPEED #ENDIF + LD A, CHANNEL_0_SILENT - OUT (SN76489_PORT_LEFT), A - OUT (SN76489_PORT_RIGHT), A + LD BC, SN76489_PORT16_LEFT + EZ80_DELAY_START(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + OUT (C), A + LD BC, SN76489_PORT16_RIGHT + OUT (C), A LD A, CHANNEL_1_SILENT - OUT (SN76489_PORT_LEFT), A - OUT (SN76489_PORT_RIGHT), A + LD BC, SN76489_PORT16_LEFT + EZ80_DELAY_WAIT(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + OUT (C), A + LD BC, SN76489_PORT16_RIGHT + OUT (C), A LD A, CHANNEL_2_SILENT - OUT (SN76489_PORT_LEFT), A - OUT (SN76489_PORT_RIGHT), A + LD BC, SN76489_PORT16_LEFT + EZ80_DELAY_WAIT(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + OUT (C), A + LD BC, SN76489_PORT16_RIGHT + OUT (C), A LD A, CHANNEL_3_SILENT - OUT (SN76489_PORT_LEFT), A - OUT (SN76489_PORT_RIGHT), A + LD BC, SN76489_PORT16_LEFT + EZ80_DELAY_WAIT(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + OUT (C), A + LD BC, SN76489_PORT16_RIGHT + OUT (C), A #IFDEF SBCV2004 LD A,(HB_RTCVAL) @@ -174,9 +201,12 @@ SN7_PLAY: AUDTRACE_D AUDTRACE_CR + EZ80_DELAY_START(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + LD A, (SN7_PENDING_PERIOD + 1) CP $FF JR Z, SN7_PLAY1 ; PERIOD IS TOO LARGE, UNABLE TO PLAY + CALL SN7_APPLY_VOL CALL SN7_APPLY_PRD @@ -281,8 +311,12 @@ SN7_APPLY_VOL: ; APPLY VOLUME TO BOTH LEFT AND RIGHT CHANNELS POP AF #ENDIF - OUT (SN76489_PORT_LEFT), A - OUT (SN76489_PORT_RIGHT), A + LD BC, SN76489_PORT16_LEFT + EZ80_DELAY_WAIT(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + OUT (C), A + + LD BC, SN76489_PORT16_RIGHT + OUT (C), A #IFDEF SBCV2004 LD A,(HB_RTCVAL) @@ -295,6 +329,7 @@ SN7_APPLY_VOL: ; APPLY VOLUME TO BOTH LEFT AND RIGHT CHANNELS RET SN7_APPLY_PRD: + PUSH DE PUSH BC PUSH AF @@ -326,8 +361,12 @@ SN7_APPLY_PRD: POP AF #ENDIF - OUT (SN76489_PORT_LEFT), A - OUT (SN76489_PORT_RIGHT), A + LD BC, SN76489_PORT16_LEFT + EZ80_DELAY_WAIT(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + OUT (C), A + + LD BC, SN76489_PORT16_RIGHT + OUT (C), A #IFDEF SBCV2004 LD A,(HB_RTCVAL) @@ -363,8 +402,14 @@ SN7_APPLY_PRD: POP AF #ENDIF - OUT (SN76489_PORT_LEFT), A - OUT (SN76489_PORT_RIGHT), A + EZ80_DELAY_WAIT(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + + LD BC, SN76489_PORT16_LEFT + EZ80_DELAY_WAIT(SN76489_IO_DELAY, SN7_DELAY_COUNTER) + OUT (C), A + + LD BC, SN76489_PORT16_RIGHT + OUT (C), A #IFDEF SBCV2004 LD A,(HB_RTCVAL) @@ -413,6 +458,11 @@ SN7_PENDING_VOLUME SN7_PENDING_DURATION .DW 0 ; PENDING DURATION (16 BITS) +#IF (CPUFAM == CPU_EZ80) +SN7_DELAY_COUNTER: + .DW 0 +#ENDIF + STR_MESSAGELT .DB "\r\nSN76489: LEFT IO=0x$" STR_MESSAGERT .DB ", RIGHT IO=0x$"