diff --git a/Binary/Apps/Tunes/ReadMe.txt b/Binary/Apps/Tunes/ReadMe.txt index 366efefe..3c41d421 100644 --- a/Binary/Apps/Tunes/ReadMe.txt +++ b/Binary/Apps/Tunes/ReadMe.txt @@ -7,4 +7,4 @@ *********************************************************************** This directory contains some sample ProTracker and MYM sound -files that can be played by the TUNE application. \ No newline at end of file +files that can be played by the TUNE or VGMPLAY application. \ No newline at end of file diff --git a/Source/Apps/TEST/sound/Scales.asm b/Source/Apps/TEST/sound/Scales.asm new file mode 100644 index 00000000..bf91ea81 --- /dev/null +++ b/Source/Apps/TEST/sound/Scales.asm @@ -0,0 +1,145 @@ +; + + .ORG $0100 + +; SCALES ON ALL THREE CHANNELS + +; JR SKIP + + LD B,3 +NEXTCH0 LD A,B + DEC A + LD (CHANNEL),A + PUSH BC ; ACROSS + CALL SCALE ; ALL + POP BC ; CHANNELS + DJNZ NEXTCH0 + +; CONSTANT TONE ON ALL THREE CHANNELS, SCALE VOLUME +SKIP: + LD HL,332+48 ; TONE + LD (NOTE),HL +; + LD B,3 +NEXTCH1 LD A,B + DEC A + LD (CHANNEL),A + PUSH BC ; ACROSS + CALL TONE ; ALL + POP BC ; CHANNELS + DJNZ NEXTCH1 + + RET + +TONE: LD B,50H ; RESET + LD C,0 + RST 08 +; +NEXT1: LD B,51H ; VOLUME + LD C,0 + LD A,(VOLUME) + LD L,A + RST 08 +; + LD B,53H ; NOTE + LD C,0 + LD HL,(NOTE) + RST 08 +; + LD B,54H ; PLAY + LD C,0 + LD A,(CHANNEL) + LD D,A + RST 08 +; + CALL DELAY +; + LD A,(VOLUME) + DEC A + LD (VOLUME),A + JR NZ,NEXT1 +; + LD B,51H ; VOLUME + LD C,0 + LD L,00H + RST 08 +; + LD B,54H ; PLAY + LD C,0 + LD A,(CHANNEL) + LD D,A + RST 08 +; + RET +; +; +; +SCALE: LD B,50H ; RESET + LD C,0 + RST 08 +; + LD B,51H ; VOLUME + LD C,0 + LD L,80H + RST 08 +; + LD HL,380 + LD (NOTE),HL +; +NEXT0: LD B,53H ; NOTE + LD C,0 + LD HL,(NOTE) + RST 08 +; + LD B,54H ; PLAY + LD C,0 + LD A,(CHANNEL) + LD D,A + RST 08 +; + OR A + JR Z,NEXT2 + LD C,9 + LD DE,BADFLAG + CALL 5 + JR NEXT3 +; +NEXT2: CALL DELAY +; +NEXT3: LD HL,(NOTE) + DEC HL + LD A,L + LD (NOTE),A + LD A,H + LD (NOTE+1),A + OR L +; + JR NZ,NEXT0 +; + LD B,51H ; VOLUME + LD C,0 + LD L,00H + RST 08 +; + LD B,54H ; PLAY + LD C,0 + LD A,(CHANNEL) + LD D,A + RST 08 +; + RET +; +DELAY: LD HL,-1 +DELAY1: DEC HL + LD A,H + OR L + JR NZ,DELAY1 + RET +; +BADFLAG .DB '*', $0D, $0A, '$' +NOTE .DW 128 +VOLUME .DB 0 +CHANNEL .DB 0 +; + .END + diff --git a/Source/Apps/VGM/Build.cmd b/Source/Apps/VGM/Build.cmd index cdd1711e..ac9cfc07 100644 --- a/Source/Apps/VGM/Build.cmd +++ b/Source/Apps/VGM/Build.cmd @@ -9,4 +9,4 @@ tasm -t180 -g3 -fFF -dWBW vgmplay.asm vgmplay.com vgmplay.lst || exit /b tasm -t180 -g3 -fFF -dWBW ym2612.asm ym2612.com ym2612.lst || exit /b copy /Y vgmplay.com ..\..\..\Binary\Apps\ || exit /b -copy /Y Tunes\*.* ..\..\..\Binary\Apps\Tunes\ || exit /b \ No newline at end of file +copy /Y Tunes\*.* ..\..\..\Binary\Apps\Tunes\ || exit /b diff --git a/Source/Apps/VGM/Makefile b/Source/Apps/VGM/Makefile index c410aec2..58cc9428 100644 --- a/Source/Apps/VGM/Makefile +++ b/Source/Apps/VGM/Makefile @@ -10,6 +10,9 @@ DEPS := vgmplay.asm $(shell find . -name '*.inc') vgmplay.com: $(DEPS) $(TASM) -dWBW vgmplay.asm vgmplay.com vgmplay.lst +ym2612.com: + $(TASM) -dWBW ym2612.asm ym2612.com ym2612.lst + all:: mkdir -p $(DEST)/Tunes cp Tunes/* $(DEST)/Tunes diff --git a/Source/Apps/VGM/Tunes/AGGRESS.VGM b/Source/Apps/VGM/Tunes/AGGRESS.VGM new file mode 100644 index 00000000..fd0a3924 Binary files /dev/null and b/Source/Apps/VGM/Tunes/AGGRESS.VGM differ diff --git a/Source/Apps/VGM/Tunes/ANNA.VGM b/Source/Apps/VGM/Tunes/ANNA.VGM new file mode 100644 index 00000000..cf8f6a64 Binary files /dev/null and b/Source/Apps/VGM/Tunes/ANNA.VGM differ diff --git a/Source/Apps/VGM/Tunes/BGM.VGM b/Source/Apps/VGM/Tunes/BGM.VGM new file mode 100644 index 00000000..e71c431b Binary files /dev/null and b/Source/Apps/VGM/Tunes/BGM.VGM differ diff --git a/Source/Apps/VGM/Tunes/DESCENT.VGM b/Source/Apps/VGM/Tunes/DESCENT.VGM new file mode 100644 index 00000000..0e72d802 Binary files /dev/null and b/Source/Apps/VGM/Tunes/DESCENT.VGM differ diff --git a/Source/Apps/VGM/Tunes/ENDING.VGM b/Source/Apps/VGM/Tunes/ENDING.VGM new file mode 100644 index 00000000..dcd349bc Binary files /dev/null and b/Source/Apps/VGM/Tunes/ENDING.VGM differ diff --git a/Source/Apps/VGM/Tunes/FIELDMAP.VGM b/Source/Apps/VGM/Tunes/FIELDMAP.VGM new file mode 100644 index 00000000..efab70af Binary files /dev/null and b/Source/Apps/VGM/Tunes/FIELDMAP.VGM differ diff --git a/Source/Apps/VGM/Tunes/FOREST.VGM b/Source/Apps/VGM/Tunes/FOREST.VGM new file mode 100644 index 00000000..11d43f0d Binary files /dev/null and b/Source/Apps/VGM/Tunes/FOREST.VGM differ diff --git a/Source/Apps/VGM/Tunes/INCHINA.VGM b/Source/Apps/VGM/Tunes/INCHINA.VGM new file mode 100644 index 00000000..cb73e2c7 Binary files /dev/null and b/Source/Apps/VGM/Tunes/INCHINA.VGM differ diff --git a/Source/Apps/VGM/Tunes/QIX.VGM b/Source/Apps/VGM/Tunes/QIX.VGM new file mode 100644 index 00000000..f3d46790 Binary files /dev/null and b/Source/Apps/VGM/Tunes/QIX.VGM differ diff --git a/Source/Apps/VGM/Tunes/SHIRAKAW.VGM b/Source/Apps/VGM/Tunes/SHIRAKAW.VGM new file mode 100644 index 00000000..c6cf01b6 Binary files /dev/null and b/Source/Apps/VGM/Tunes/SHIRAKAW.VGM differ diff --git a/Source/Apps/VGM/Tunes/STARTDEM.VGM b/Source/Apps/VGM/Tunes/STARTDEM.VGM new file mode 100644 index 00000000..66b57817 Binary files /dev/null and b/Source/Apps/VGM/Tunes/STARTDEM.VGM differ diff --git a/Source/Apps/VGM/Tunes/TEDDY.VGM b/Source/Apps/VGM/Tunes/TEDDY.VGM new file mode 100644 index 00000000..4b30c562 Binary files /dev/null and b/Source/Apps/VGM/Tunes/TEDDY.VGM differ diff --git a/Source/Apps/VGM/Tunes/filthy01.vgm b/Source/Apps/VGM/Tunes/filthy01.vgm deleted file mode 100644 index c161e1f3..00000000 Binary files a/Source/Apps/VGM/Tunes/filthy01.vgm and /dev/null differ diff --git a/Source/Apps/VGM/YM2612.ASM b/Source/Apps/VGM/YM2612.ASM index bd27b33b..367dc5d6 100644 --- a/Source/Apps/VGM/YM2612.ASM +++ b/Source/Apps/VGM/YM2612.ASM @@ -26,7 +26,7 @@ ctcbase .equ $cc #DEFCONT \ rlca #DEFCONT \ jp c,$-3 -init: call ctc_config +init: ;call ctc_config setreg($22,$00) ; lfo off YM2612 initialization setreg($27,$00) ; note off ch 0 diff --git a/Source/Apps/VGM/vgmplay.asm b/Source/Apps/VGM/vgmplay.asm index e4581e1d..423843d2 100644 --- a/Source/Apps/VGM/vgmplay.asm +++ b/Source/Apps/VGM/vgmplay.asm @@ -9,122 +9,175 @@ ; YM2151 support from Ed Brindley ; ; YM2162/YM3484, GD3 support, VGM Chip identification, -; default file type, basic file size checking added by Phil Summers +; default file type, basic file size checking, polled CTC mode +; added by Phil Summers ; ; Bugs: YM2151 playback untested & no mute. +; CTC polled timing - predicted 44100 divider is too slow ; ; Assemble with: ; ; TASM -80 -b VGMPLAY.ASM VGMPLAY.COM ; +; +; A VGM file can play 44100 samples a second. This may be sound chip +; register commands or PCM data. This player does not support PCM playback +; due to the high processor speed and file size required. Typical VGM files +; available use a much lower sample rate and are playable. Where the processor +; speed is low and the sample rate is high, the playback overhead will cause +; playback speed to be inaccurate. + ;------------------------------------------------------------------------------ ; Device and system specific definitions ;------------------------------------------------------------------------------ ; -P8X180 .EQU 0 ; System configuration -RC2014 .EQU 0 -SBCECB .EQU 1 -MBC .EQU 0 -; - .IF P8X180 -RSEL .EQU 82H ; Primary AY-3-8910 Register selection -RDAT .EQU 83H ; Primary AY-3-8910 Register data -RSEL2 .EQU 88H ; Secondary AY-3-8910 Register selection -RDAT2 .EQU 89H ; Secondary AY-3-8910 Register data -PSG1REG .EQU 84H ; Primary SN76489 -PSG2REG .EQU 8AH ; Secondary SN76489 -YM2151_SEL1 .EQU 0B0H ; Primary YM2151 register selection -YM2151_DAT1 .EQU 0B1H ; Primary YM2151 register data -YM2151_SEL2 .EQU 0B2H ; Secondary YM2151 register selection -YM2151_DAT2 .EQU 0B3H ; Secondary YM2151 register data -FRAME_DLY .EQU 48 ; Frame delay (~ 1/44100) - .ENDIF -; - .IF RC2014 -RSEL .EQU 0D8H ; Primary AY-3-8910 Register selection -RDAT .EQU 0D0H ; Primary AY-3-8910 Register data -RSEL2 .EQU 0A0H ; Secondary AY-3-8910 Register selection -RDAT2 .EQU 0A1H ; Secondary AY-3-8910 Register data -PSG1REG .EQU 0FFH ; Primary SN76489 -PSG2REG .EQU 0FBH ; Secondary SN76489 -YM2151_SEL1 .EQU 0FEH ; Primary YM2151 register selection -YM2151_DAT1 .EQU 0FFH ; Primary YM2151 register data -YM2151_SEL2 .EQU 0D0H ; Secondary YM2151 register selection -YM2151_DAT2 .EQU 0D1H ; Secondary YM2151 register data -FRAME_DLY .EQU 15 ; Frame delay (~ 1/44100) - .ENDIF -; - .IF SBCECB -RSEL .EQU 0D8H ; Primary AY-3-8910 Register selection -RDAT .EQU 0D0H ; Primary AY-3-8910 Register data -RSEL2 .EQU 0A0H ; Secondary AY-3-8910 Register selection -RDAT2 .EQU 0A1H ; Secondary AY-3-8910 Register data -YMSEL .EQU 0C0H ; Primary YM2162 11000000 a1=0 a0=0 -YMDAT .EQU 0C1H ; Primary YM2162 11000001 a1=0 a0=1 -YM2SEL .EQU 0C2H ; Secondary YM2162 11000010 a1=1 a0=0 -YM2DAT .EQU 0C3H ; Secondary YM2162 11000011 a1=1 a0=1 -PSG1REG .EQU 0C6H ; Primary SN76489 -PSG2REG .EQU 0C7H ; Secondary SN76489 -YM2151_SEL1 .EQU 0FEH ; Primary YM2151 register selection -YM2151_DAT1 .EQU 0FFH ; Primary YM2151 register data -YM2151_SEL2 .EQU 0FEH ; Secondary YM2151 register selection -YM2151_DAT2 .EQU 0FFH ; Secondary YM2151 register data -FRAME_DLY .EQU 8 ; Frame delay (~ 1/44100) - .ENDIF -; - .IF MBC -RSEL .EQU 0A0H ; Primary AY-3-8910 Register selection -RDAT .EQU 0A1H ; Primary AY-3-8910 Register data -RSEL .EQU 0D8H ; Secondary AY-3-8910 Register selection -RDAT .EQU 0D0H ; Secondary AY-3-8910 Register data -YMSEL .EQU 0C0H ; 11000000 a1=0 a0=0 -YMDAT .EQU 0C1H ; 11000001 a1=0 a0=1 -YM2SEL .EQU 0C2H ; 11000010 a1=1 a0=0 -YM2DAT .EQU 0C3H ; 11000011 a1=1 a0=1 -PSGREG .EQU 0C6H ; Primary SN76489 -PSG2REG .EQU 0C7H ; Secondary SN76489 -YM2151_SEL1 .EQU 0FEH ; Primary YM2151 register selection -YM2151_DAT1 .EQU 0FFH ; Primary YM2151 register data -YM2151_SEL2 .EQU 0FEH ; Secondary YM2151 register selection -YM2151_DAT2 .EQU 0FFH ; Secondary YM2151 register data -FRAME_DLY .EQU 10 ; Frame delay (~ 1/44100) - .ENDIF -; -;------------------------------------------------------------------------------ -; Your customer overrides can go in here i.e. ports -;------------------------------------------------------------------------------ -; -;RSEL .SET 09AH ; Primary AY-3-8910 Register selection -;RDAT .SET 09BH ; Primary AY-3-8910 Register data -; -;------------------------------------------------------------------------------ -; Frame delay overide values for different processor speeds. -;------------------------------------------------------------------------------ -; -;FRAME_DLY .SET 10 ; 1Mhz ; not -;FRAME_DLY .SET 10 ; 2Mhz ; implemented -;FRAME_DLY .SET 10 ; 4Mhz ; yet -;FRAME_DLY .SET 15 ; 8Mhz -;FRAME_DLY .SET 10 ; 10Mhz -;FRAME_DLY .SET 20 ; 12Mhz -; -;------------------------------------------------------------------------------ -; Frame delay values for pal/ntsc -;------------------------------------------------------------------------------ -; -D60 .EQU 735 -D50 .EQU 882 +custom .equ 0 ; System configurations +P8X180 .equ 1 +RC2014 .equ 2 +sbcecb .equ 3 +MBC .equ 4 +; +plt_romwbw .equ 1 ; Build for ROMWBW? +plt_type .equ custom ; Select build configuration +debug .equ 1 ; Debugging output +; +#IF (plt_type=custom) +RSEL .equ 0D8H ; Primary AY-3-8910 Register selection +RDAT .equ 0D0H ; Primary AY-3-8910 Register data +RSEL .SET 09AH ; Primary AY-3-8910 Register selection +RDAT .SET 09BH ; Primary AY-3-8910 Register data +RSEL2 .equ 88H ; Secondary AY-3-8910 Register selection +RDAT2 .equ 89H ; Secondary AY-3-8910 Register data +VGMBASE .equ $C0 +YMSEL .equ VGMBASE+00H ; Primary YM2162 11000000 a1=0 a0=0 +YMDAT .equ VGMBASE+01H ; Primary YM2162 11000001 a1=0 a0=1 +YM2SEL .equ VGMBASE+02H ; Secondary YM2162 11000010 a1=1 a0=0 +YM2DAT .equ VGMBASE+03H ; Secondary YM2162 11000011 a1=1 a0=1 +PSG1REG .equ VGMBASE+08H ; Primary SN76489 +PSG2REG .equ VGMBASE+09H ; Secondary SN76489 +ctcbase .equ VGMBASE+0CH ; CTC base address +YM2151_SEL1 .equ 0FEH ; Primary YM2151 register selection +YM2151_DAT1 .equ 0FFH ; Primary YM2151 register data +YM2151_SEL2 .equ 0FEH ; Secondary YM2151 register selection +YM2151_DAT2 .equ 0FFH ; Secondary YM2151 register data +FRAME_DLY .equ 10 ; Frame delay (~ 1/44100) +plt_cpuspd .equ 6 ; Non ROMWBW cpu speed default +#ENDIF +; +#IF (plt_type=P8X180) +RSEL .equ 82H ; Primary AY-3-8910 Register selection +RDAT .equ 83H ; Primary AY-3-8910 Register data +RSEL2 .equ 88H ; Secondary AY-3-8910 Register selection +RDAT2 .equ 89H ; Secondary AY-3-8910 Register data +PSG1REG .equ 84H ; Primary SN76489 +PSG2REG .equ 8AH ; Secondary SN76489 +YM2151_SEL1 .equ 0B0H ; Primary YM2151 register selection +YM2151_DAT1 .equ 0B1H ; Primary YM2151 register data +YM2151_SEL2 .equ 0B2H ; Secondary YM2151 register selection +YM2151_DAT2 .equ 0B3H ; Secondary YM2151 register data +ctcbase .equ 000H ; CTC base address +YMSEL .equ 000H ; Primary YM2162 11000000 a1=0 a0=0 +YMDAT .equ 000H ; Primary YM2162 11000001 a1=0 a0=1 +YM2SEL .equ 000H ; Secondary YM2162 11000010 a1=1 a0=0 +YM2DAT .equ 000H ; Secondary YM2162 11000011 a1=1 a0=1 +FRAME_DLY .equ 48 ; Frame delay (~ 1/44100) +plt_cpuspd .equ 20 ; Non ROMWBW cpu speed default +#ENDIF +; +#IF (plt_type=RC2014) +RSEL .equ 0D8H ; Primary AY-3-8910 Register selection +RDAT .equ 0D0H ; Primary AY-3-8910 Register data +RSEL2 .equ 0A0H ; Secondary AY-3-8910 Register selection +RDAT2 .equ 0A1H ; Secondary AY-3-8910 Register data +PSG1REG .equ 0FFH ; Primary SN76489 +PSG2REG .equ 0FBH ; Secondary SN76489 +YM2151_SEL1 .equ 0FEH ; Primary YM2151 register selection +YM2151_DAT1 .equ 0FFH ; Primary YM2151 register data +YM2151_SEL2 .equ 0D0H ; Secondary YM2151 register selection +YM2151_DAT2 .equ 0D1H ; Secondary YM2151 register data +ctcbase .equ 000H ; CTC base address +YMSEL .equ 000H ; Primary YM2162 11000000 a1=0 a0=0 +YMDAT .equ 000H ; Primary YM2162 11000001 a1=0 a0=1 +YM2SEL .equ 000H ; Secondary YM2162 11000010 a1=1 a0=0 +YM2DAT .equ 000H ; Secondary YM2162 11000011 a1=1 a0=1 +FRAME_DLY .equ 12 ; Frame delay (~ 1/44100) +plt_cpuspd .equ 7 ; Non ROMWBW cpu speed default +#ENDIF +; +#IF (plt_type=sbcecb) +RSEL .equ 0D8H ; Primary AY-3-8910 Register selection +RDAT .equ 0D0H ; Primary AY-3-8910 Register data +RSEL2 .equ 0A0H ; Secondary AY-3-8910 Register selection +RDAT2 .equ 0A1H ; Secondary AY-3-8910 Register data +VGMBASE .equ $C0 +YMSEL .equ VGMBASE+00H ; Primary YM2162 11000000 a1=0 a0=0 +YMDAT .equ VGMBASE+01H ; Primary YM2162 11000001 a1=0 a0=1 +YM2SEL .equ VGMBASE+02H ; Secondary YM2162 11000010 a1=1 a0=0 +YM2DAT .equ VGMBASE+03H ; Secondary YM2162 11000011 a1=1 a0=1 +PSG1REG .equ VGMBASE+08H ; Primary SN76489 +PSG2REG .equ VGMBASE+09H ; Secondary SN76489 +ctcbase .equ VGMBASE+0CH ; CTC base address +YM2151_SEL1 .equ 0FEH ; Primary YM2151 register selection +YM2151_DAT1 .equ 0FFH ; Primary YM2151 register data +YM2151_SEL2 .equ 0FEH ; Secondary YM2151 register selection +YM2151_DAT2 .equ 0FFH ; Secondary YM2151 register data +FRAME_DLY .equ 13 ; Frame delay (~ 1/44100) +plt_cpuspd .equ 8 ; Non ROMWBW cpu speed default +#ENDIF +; +#IF (plt_type=MBC) +RSEL .equ 0A0H ; Primary AY-3-8910 Register selection +RDAT .equ 0A1H ; Primary AY-3-8910 Register data +RSEL2 .equ 0D8H ; Secondary AY-3-8910 Register selection +RDAT2 .equ 0D0H ; Secondary AY-3-8910 Register data +YMSEL .equ 0C0H ; 11000000 a1=0 a0=0 +YMDAT .equ 0C1H ; 11000001 a1=0 a0=1 +YM2SEL .equ 0C2H ; 11000010 a1=1 a0=0 +YM2DAT .equ 0C3H ; 11000011 a1=1 a0=1 +PSG1REG .equ 0C6H ; Primary SN76489 +PSG2REG .equ 0C7H ; Secondary SN76489 +ctcbase .equ 000H ; CTC base address +YM2151_SEL1 .equ 0FEH ; Primary YM2151 register selection +YM2151_DAT1 .equ 0FFH ; Primary YM2151 register data +YM2151_SEL2 .equ 0FEH ; Secondary YM2151 register selection +YM2151_DAT2 .equ 0FFH ; Secondary YM2151 register data +FRAME_DLY .equ 13 ; Frame delay (~ 1/44100) +plt_cpuspd .equ 8 ; Non ROMWBW cpu speed default +#ENDIF +; +;------------------------------------------------------------------------------ +; Configure timing loop +;------------------------------------------------------------------------------ +; +cpu_loop: .equ 0 +ctc_poll: .equ 1 +ctc_int: .equ 2 ; not implemented +; +delay_type: .equ ctc_poll ; cpu timed loop or utilize ctc +delay_wait .equ 0 ; funny wait mode +; +D60 .equ 735 ; 735x60=44100 Frame delay values for ntsc +D50 .equ 882 ; 882x50=44100 Frame delay values for pal +; +;------------------------------------------------------------------------------ +; CTC Defaults +;------------------------------------------------------------------------------ +; +ctcdiv0 .equ 1 ; Divider chain for 3.579545MHz input +ctcdiv1 .equ 1 ; Ctc with 3 step divider base address +ctcdiv2 .equ 16 +ctcdiv3 .equ 3 ; 3579545 / 1 / 2 / 41 = 43653 = 1% error ; ;------------------------------------------------------------------------------ ; Processor speed control for SBCV2004+ ;------------------------------------------------------------------------------ ; ;#DEFINE SBCV2004 ; My SBC board at 12Mhz needs this to switch to -HB_RTCVAL .EQU 0FFEEH ; 6MHz for it to work with the ECB-VGM reliably. -RTCIO .EQU 070H - +HB_RTCVAL .equ 0FFEEH ; 6MHz for it to work with the ECB-VGM reliably. +RTCIO .equ 070H +; ;------------------------------------------------------------------------------ -; YM2162 Register write macros +; YM2162 Register write macros - with wait and timeout ;------------------------------------------------------------------------------ ; #DEFINE setreg(reg,val) \ @@ -132,53 +185,57 @@ RTCIO .EQU 070H #DEFCONT \ out (YMSEL),a #DEFCONT \ ld a,val #DEFCONT \ out (YMDAT),a +#DEFCONT \ ld b,0 #DEFCONT \ in a,(YMSEL) #DEFCONT \ rlca -#DEFCONT \ jp c,$-3 +#DEFCONT \ jp nc,$+5 +#DEFCONT \ djnz $-6 ; #DEFINE setreg2(reg,val) \ #DEFCONT \ ld a,reg #DEFCONT \ out (YM2SEL),a #DEFCONT \ ld a,val #DEFCONT \ out (YM2DAT),a +#DEFCONT \ ld b,0 #DEFCONT \ in a,(YMSEL) #DEFCONT \ rlca -#DEFCONT \ jp c,$-3 +#DEFCONT \ jp nc,$+5 +#DEFCONT \ djnz $-6 ;------------------------------------------------------------------------------ ; VGM Codes ;------------------------------------------------------------------------------ -VGM_GG_W .EQU 04FH ; GAME GEAR PSG STEREO. WRITE DD TO PORT 0X06 -VGM_PSG1_W .EQU 050H ; PSG (SN76489/SN76496) #1 WRITE VALUE DD -VGM_PSG2_W .EQU 030H ; PSG (SN76489/SN76496) #2 WRITE VALUE DD -VGM_YM26121_W .EQU 052H ; YM2612 #1 WRITE VALUE DD -VGM_YM26122_W .EQU 053H ; YM2612 #2 WRITE VALUE DD -VGM_WNS .EQU 061H ; WAIT N SAMPLES -VGM_W735 .EQU 062H ; WAIT 735 SAMPLES (1/60TH SECOND) -VGM_W882 .EQU 063H ; WAIT 882 SAMPLES (1/50TH SECOND) -VGM_ESD .EQU 066H ; END OF SOUND DATA -VGM_YM21511_W .EQU 054H ; YM2612 #1 WRITE VALUE DD -VGM_YM21512_W .EQU 0A4H ; YM2612 #2WRITE VALUE DD +VGM_GG_W .equ 04FH ; GAME GEAR PSG STEREO. WRITE DD TO PORT 0X06 +VGM_PSG1_W .equ 050H ; PSG (SN76489/SN76496) #1 WRITE VALUE DD +VGM_PSG2_W .equ 030H ; PSG (SN76489/SN76496) #2 WRITE VALUE DD +VGM_YM26121_W .equ 052H ; YM2612 #1 WRITE VALUE DD +VGM_YM26122_W .equ 053H ; YM2612 #2 WRITE VALUE DD +VGM_WNS .equ 061H ; WAIT N SAMPLES +VGM_W735 .equ 062H ; WAIT 735 SAMPLES (1/60TH SECOND) +VGM_W882 .equ 063H ; WAIT 882 SAMPLES (1/50TH SECOND) +VGM_ESD .equ 066H ; END OF SOUND DATA +VGM_YM21511_W .equ 054H ; YM2612 #1 WRITE VALUE DD +VGM_YM21512_W .equ 0A4H ; YM2612 #2 WRITE VALUE DD ;------------------------------------------------------------------------------ ; Generic CP/M definitions ;------------------------------------------------------------------------------ -BOOT .EQU 0000H ; boot location -BDOS .EQU 0005H ; bdos entry point -FCB .EQU 005CH ; file control block -FCBCR .EQU FCB + 20H ; fcb current record -BUFF .EQU 0080H ; DMA buffer -TOPM .EQU 0002H ; Top of memory +BOOT .equ 0000H ; boot location +BDOS .equ 0005H ; bdos entry point +FCB .equ 005CH ; file control block +FCBCR .equ FCB + 20H ; fcb current record +BUFF .equ 0080H ; DMA buffer +TOPM .equ 0002H ; Top of memory -PRINTF .EQU 9 ; BDOS print string function -OPENF .EQU 15 ; BDOS open file function -CLOSEF .EQU 16 ; BDOS close file function -READF .EQU 20 ; BDOS sequential read function +PRINTF .equ 9 ; BDOS print string function +OPENF .equ 15 ; BDOS open file function +CLOSEF .equ 16 ; BDOS close file function +READF .equ 20 ; BDOS sequential read function -CR .EQU 0DH ; carriage return -LF .EQU 0AH ; line feed +CR .equ 0DH ; carriage return +LF .equ 0AH ; line feed ;------------------------------------------------------------------------------ ; Program Start @@ -188,12 +245,29 @@ LF .EQU 0AH ; line feed LD (OLDSTACK),SP ; save old stack pointer LD SP,STACK ; set new stack pointer - - LD DE,MSG_WELC ; Welcome Message - CALL PRTSTR - +; +#IF (delay_type==cpu_loop) + call setfdelay ; Setup the frame delay based on cpu speed +#ENDIF +; +#IF (delay_type==ctc_poll) + call cfgctc_poll ; If building for polled ctc, initialize it +#ENDIF +; +#IF (delay_type==ctc_int) ; If building for interrupt driven ctc, initialize it + call cfgctc_int +#ENDIF +; +#IF (debug) +; LD A,0 ; tone to validate presence +;TST: LD C,PSG1REG +; OUT (C),A +; LD C,PSG2REG +; OUT (C),A +; JR TST +#ENDIF + call welcome ; Welcome message and build debug info CALL READVGM ; Read in the VGM file - CALL VGMINFO ; Check and display VGM Information LD HL, (VGMDATA + 34H) ; Determine start of VGM @@ -209,21 +283,50 @@ _S1 LD DE, VGMDATA + 34H LD (VGMDLY), HL MAINLOOP CALL PLAY ; Play one frame - - LD C,6 ; Check for keypress +; + LD HL,KEYCHK ; Check for keypress + DEC (HL) + JR NZ,NO_CHK + LD C,6 ; Every 256 commands LD E,0FFH CALL BDOS OR A JR NZ,EXIT +NO_CHK: +#IF (delay_type==cpu_loop) + LD HL,(VGMDLY) ; Frame delay +fdelay: .equ $+1 +lp1: LD B,FRAME_DLY ; 44100 one frame = 0.0000226757 seconds + DJNZ $ + DEC HL + LD A,H + OR L + JR NZ,lp1 +#ENDIF - LD HL,(VGMDLY) ; Frame delay -L1 LD B,FRAME_DLY - DJNZ $ - DEC HL - LD A,H - OR L - JR NZ,L1 - +#IF (delay_type==ctc_poll) + LD HL,(VGMDLY) ; Frame delay +lp1: in a,(ctcch3) ; wait for counter to reach zero + dec a + jr nz,lp1 +#IF (delay_wait) +lp2: in a,(ctcch3) ; wait for counter to pass zero + dec a + jr z,lp2 + +lp3: in a,(ctcch3) ; wait for counter to reach zero + dec a + jr nz,lp3 +#ENDIF + DEC HL + LD A,H + OR L + JR NZ,lp1 +#ENDIF +; +#IF (delay_type==ctc_int) +#ENDIF +; JR MAINLOOP ; ;------------------------------------------------------------------------------ @@ -240,6 +343,194 @@ EXIT: CALL VGMDEVICES ; Display devices used EXIT_ERR: CALL PRTSTR ; Generic message or error LD SP, (OLDSTACK) ; Exit to CP/M RST 00H + DI + HALT +; +;------------------------------------------------------------------------------ +; Welcome +;------------------------------------------------------------------------------ +; +welcome: LD DE,MSG_WELC ; Welcome Message + CALL PRTSTR +; +#IF (plt_romwbw) + LD DE,MSG_ROMWBW ; display system type + CALL PRTSTR +#ENDIF +; + LD A,delay_type ; display build type + LD DE,MSG_CPU + CALL PRTIDXDEA +; + LD A,plt_type ; display system type + LD DE,MSG_CUSTOM + CALL PRTIDXDEA + call CRLF +; +#IF (debug) +#IF (delay_type==cpu_loop) + ld a,'f' ; Display frame rate delay + call PRTCHR + call PRTDOT + ld a,(fdelay) + call PRTDECB + LD A,' ' +#ENDIF + CALL PRTCHR + ld a,'c' + call PRTCHR + call PRTDOT + ld a,ctcdiv0 ; Display ctc divider values + call PRTDECB + CALL PRTDOT + ld a,ctcdiv1 + call PRTDECB + CALL PRTDOT + ld a,ctcdiv2 + call PRTDECB + CALL PRTDOT + ld a,ctcdiv3 + call PRTDECB +; +#IF (delay_wait) + ld a,' ' + CALL PRTCHR + LD A,'w' ; Display if using double wait + CALL PRTCHR +#ENDIF +#ENDIF + CALL CRLF + ret +; +;------------------------------------------------------------------------------ +; Setup frame delay value - Loop count for DJNZ $ loop +;------------------------------------------------------------------------------ +; +setfdelay: +#IF (delay_type==cpu_loop) +#IF (plt_romwbw) + LD BC,$F8F0 ; GET CPU SPEED + RST 08 ; FROM HBIOS + LD A,L ; +#ELSE + ld a,plt_cpuspd ; USE STANDALONE CPU SPEED +#ENDIF + LD HL,CLKTBL-1 ; CPU SPEED + ADD A,L ; INDEXES + LD L,A ; INTO + ADC A,H ; TABLE + SUB L + LD H,A ; LOOK IT UP IN THE + LD A,(HL) ; CLOCK TABLE + + LD (fdelay),A ; SAVE LOOP COUNTER FOR CPU SPEED + RET + +;------------------------------------------------------------------------------ +; Frame delay values for different processor speeds. +;------------------------------------------------------------------------------ +; +; 1/44100hz = 22676ns +; 16Mhz = 62.5ns : DJNZ $ = 1 frame delay= 22676ns/13*62.5ns = 27.91 +; 12Mhz = 83.3ns : DJNZ $ = 1 frame delay= 22676ns/13*83.3ns = 20.94 +; 10Mhz = 100ns : DJNZ $ = 1 frame delay= 22676ns/13*100ns = 17.44 +; 8Mhz = 125ns : DJNZ $ = 1 frame delay= 22676ns/13*125ns = 13.95 +; 7.3728Mhz = 135.6ns : DJNZ $ = 1 frame delay= 22676ns/13*135.6ns = 12.86 +; 6Mhz = 166.6s : DJNZ $ = 1 frame delay= 22676ns/13*166.6ns = 10.47 +; 4Mhz = 250ns : DJNZ $ = 1 frame delay= 22676ns/13*250ns = 6.98 +; 2Mhz = 500ns : DJNZ $ = 1 frame delay= 22676ns/13*500ns = 3.49 +; 1Mhz = 1000ns : DJNZ $ = 1 frame delay= 22676ns/13*1000ns = 1.74 +; +CLKTBL: .DB 1 ; 1Mhz ; none of these + .DB 3 ; 2Mhz ; have been + .DB 0 ; 3Mhz ; validated + .DB 6 ; 4Mhz + .DB 0 ; 5Mhz + .DB 10 ; 6Mhz + .DB 12 ; 7Mhz 7.3728Mhz + .DB 13 ; 8Mhz + .DB 0 ; 9Mhz + .DB 17 ; 10Mhz + .DB 0 ; 11Mhz + .DB 20 ; 12Mhz + .DB 0 ; 13Mhz + .DB 0 ; 14Mhz + .DB 0 ; 15Mhz + .DB 27 ; 16Mhz + .DB 0 ; 17Mhz + .DB 0 ; 18Mhz + .DB 0 ; 19Mhz + .DB 0 ; 20Mhz +#ENDIF +; +;------------------------------------------------------------------------------ +; Initialize CTC +;------------------------------------------------------------------------------ +; +; %01010011 ; CTC DEFAULT CONFIG +; %01010111 ; CTC COUNTER MODE CONFIG +; %11010111 ; CTC COUNTER INTERRUPT MODE CONFIG +; |||||||+-- CONTROL WORD FLAG +; ||||||+--- SOFTWARE RESET +; |||||+---- TIME CONSTANT FOLLOWS +; ||||+----- AUTO TRIGGER WHEN TIME CONST LOADED +; |||+------ RISING EDGE TRIGGER +; ||+------- TIMER MODE PRESCALER (0=16, 1=256) +; |+-------- COUNTER MODE +; +--------- INTERRUPT ENABLE +; +cfgctc_poll: +; +ctcch0 .equ ctcbase +ctcch1 .equ ctcbase+1 +ctcch2 .equ ctcbase+2 +ctcch3 .equ ctcbase+3 +; +ctccfg0 .equ %01010011 +ctccfg1 .equ %01010111 +ctccfg2 .equ %01010111 +ctccfg3 .equ %01010111 +; + ld a,ctccfg0 & $7f ; ; Channel 0 + out (ctcch0),a +; + ld a,ctccfg1 & $7f ; Channel 1 + out (ctcch1),a ; + ld a,ctcdiv1 & $ff ; + out (ctcch1),a ; +; + ld a,ctccfg2 & $7f ; Channel 2 + out (ctcch2),a ; + ld a,ctcdiv2 & $ff ; + out (ctcch2),a ; +; + ld a,ctccfg3 & $7f ; Channel 3 + out (ctcch3),a ; + ld a,ctcdiv3 & $ff ; + out (ctcch3),a ; +; + ret +; +#IF (debug) +ctctest: + ld b,0 + +ctclp1: in a,(ctcch3) ; wait for counter to reach zero + dec a + jr nz,ctclp1 + +ctclp2: in a,(ctcch3) ; wait for counter to pass zero + dec a + jr z,ctclp2 + + call PRTDOT +; + djnz ctclp1 +#ENDIF + ret +; +cfgctc_int: + ret ; ;------------------------------------------------------------------------------ ; Read VGM file into memory @@ -406,18 +697,19 @@ NEXT LD A, (HL) LD HL, (VGMDATA + 1CH) ; Loop offset LD A, H OR L - JP Z, EXIT + JP Z, EXIT LD DE, VGMDATA + 1CH ADD HL, DE LD (VGMPOS), HL JR NEXT -NEXT1 CP VGM_GG_W ; Game Gear SN76489 stereo. Ignored - JR NZ, PSG - LD IX,VGM_DEV - SET 0,(IX+1) - INC HL - JR NEXT +NEXT1: +; CP VGM_GG_W ; Game Gear SN76489 stereo. Ignored +; JR NZ, PSG +; LD IX,VGM_DEV +; SET 0,(IX+1) +; INC HL +; JR NEXT ; SN76489 SECTION @@ -426,7 +718,6 @@ PSG CP VGM_PSG1_W ; Write byte to SN76489. LD A, (HL) INC HL OUT (PSG1REG), A - LD IX,VGM_DEV SET 0,(IX+0) JR NEXT @@ -435,7 +726,6 @@ PSG2 CP VGM_PSG2_W ; Write byte to second SN76489. LD A, (HL) INC HL OUT (PSG2REG), A - LD IX,VGM_DEV SET 1,(IX+0) JR NEXT @@ -452,14 +742,12 @@ AY CP 0A0H LD A, (HL) INC HL OUT (RDAT2), A - LD IX,VGM_DEV SET 2,(IX+0) JR NEXT AY1 OUT (RSEL), A LD A, (HL) INC HL OUT (RDAT), A - LD IX,VGM_DEV SET 3,(IX+0) JR NEXT @@ -473,7 +761,6 @@ YM2162_1 CP VGM_YM26121_W LD A,(HL) OUT (YMDAT),A INC HL - LD IX,VGM_DEV SET 4,(IX+0) JP NEXT ; @@ -485,7 +772,6 @@ YM2162_2 CP VGM_YM26122_W LD A,(HL) OUT (YM2DAT),A INC HL - LD IX,VGM_DEV SET 4,(IX+0) ; 2nd channel JP NEXT @@ -499,7 +785,6 @@ YM2151_1 CP VGM_YM21511_W LD A,(HL) OUT (YM2151_DAT1),A INC HL - LD IX,VGM_DEV SET 6,(IX+0) JP NEXT ; @@ -511,7 +796,6 @@ YM2151_2 CP VGM_YM21512_W LD A,(HL) OUT (YM2151_DAT2),A INC HL - LD IX,VGM_DEV SET 7,(IX+0) JP NEXT ; @@ -551,8 +835,7 @@ WAIT1 CP 70H ; WAIT 0-15 SAMPLES LD (VGMDLY), HL RET ; -UNK LD IX,VGM_DEV ; Set flag for - SET 0,(IX+1) ; unknown device +UNK: SET 0,(IX+1) ; unknown device INC HL ; Try and skip JP NEXT ; @@ -609,12 +892,6 @@ CHKDEV: AND %00000011 ; Display CALL PRTCHR ; Skip if not CALL PRTSTR ; used. RET - -DEBUG: PUSH AF - LD A,'*' - CALL PRTCHR - POP AF - RET ; ;------------------------------------------------------------------------------ ; Mute Devices. @@ -939,6 +1216,28 @@ FASTIO: RET ; ;------------------------------------------------------------------------------ +; PRINT THE nTH STRING IN A LIST OF STRINGS WHERE EACH IS TERMINATED BY 0 +; A REGISTER DEFINES THE nTH STRING IN THE LIST TO PRINT AND DE POINTS +; TO THE START OF THE STRING LIST. +;------------------------------------------------------------------------------ +; +PRTIDXDEA: + LD C,A + OR A +PRTIDXDEA1: + JR Z,PRTIDXDEA3 ; FOUND TARGET SO EXIT +PRTIDXDEA2: + LD A,(DE) ; LOOP UNIT + INC DE ; WE REACH + OR A ; END OF STRING + JR NZ,PRTIDXDEA2 + DEC C ; AT STRING END. SO GO + JR PRTIDXDEA1 ; CHECK FOR INDEX MATCH +PRTIDXDEA3: + CALL PRTSTR ; DISPLAY THE STRING + RET +; +;------------------------------------------------------------------------------ ; External routines. ;------------------------------------------------------------------------------ ; @@ -948,8 +1247,8 @@ FASTIO: ; Strings and constants. ;------------------------------------------------------------------------------ ; -MSG_WELC: .DB "VGM Player for RomWBW v0.3, 2-Jul-2022",CR,LF -; .DB "J.B. Langston/Marco Maccaferri/Phil Summers",CR,LF +MSG_WELC: .DB "VGM Player v0.4, 11-Dec-2022" +; .DB CR,LF, "J.B. Langston/Marco Maccaferri/Ed Brindley/Phil Summers",CR,LF .DB 0 MSG_BADF: .DB "Not a VGM file",CR,LF,0 MSG_PO .DB "Played on : ",0 @@ -963,6 +1262,15 @@ MSG_NOFILE: .DB "File not found", CR, LF, 0 MSG_MEM: .DB "File to big", CR, LF, 0 MSG_TITLE: .DB " from: ",0 MSG_TRACK .DB "Playing: ",0 +MSG_CPU .DB "[cpu]",0 +MSG_CTCPOLL .DB "[ctc polled]",0 +MSG_CTCINT .DB "[ctc interrupts]",0 +MSG_ROMWBW .DB " [romwbw] ",0 +MSG_CUSTOM .DB " [custom] ",0 +MSG_P8X180 .DB " [p8x180] ",0 +MSG_RC2014 .DB " [rc2014] ",0 +MSG_SBCECB .DB " [sbc] ",0 +MSG_MBC .DB " [mbc] ",0 ; ;------------------------------------------------------------------------------ ; Variables @@ -970,10 +1278,17 @@ MSG_TRACK .DB "Playing: ",0 ; VGMPOS .DW 0 VGMDLY .DW 0 -VGMUNK_F .DB 0 ; Flag for unknown device -VGM_DEV .DB %00000000 ; yyYYAASS - .DB %00000000 ; Unimplemented device flags - +KEYCHK .DB 0 ; Counter for keypress checks +; +VGM_DEV .DB %00000000 ; IX+0 Flags for devices + ; xx...... ym2151 1 & 2 + ; ..x..... ym2612 2 (not supported) + ; ...x.... ym2612 1 + ; ....xx.. ay-3-8910 1 & 2 + ; ......xx sn76489 1 & 2 + + .DB %00000000 ; IX+1 Unimplemented device flags & future devices +; OLDSTACK .DW 0 ; original stack pointer .DS 40H ; space for stack STACK ; top of stack diff --git a/Source/HBIOS/sn76489.asm b/Source/HBIOS/sn76489.asm index b05bba74..9de9d5c8 100644 --- a/Source/HBIOS/sn76489.asm +++ b/Source/HBIOS/sn76489.asm @@ -13,8 +13,8 @@ ;====================================================================== ; #IF (PLATFORM == PLT_SBC) & (SNMODE == SNMODE_VGM) -SN76489_PORT_LEFT .EQU $C6 ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) -SN76489_PORT_RIGHT .EQU $C7 ; PORTS FOR ACCESSING THE SN76489 CHIP (RIGHT) +SN76489_PORT_LEFT .EQU $C8 ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT) +SN76489_PORT_RIGHT .EQU $C9 ; PORTS FOR ACCESSING THE SN76489 CHIP (RIGHT) ;SN7CLK .EQU 3575950 ; CLOCK SPEED DRIVING THE SN76489 CHIPS #ENDIF