/NextSID-src

NextSID for the ZX Spectrum Next

Primary LanguageAssembly


THE FOLLOWING CODE AND APPS ARE PUBLIC DOMAIN


June 27th 2021, NextSID version v0.5b Written by 9bitcolor

The sourcecode builds NEXTSID.SNX, the original test shell with a raster change applied to SID B channel.

KEYS 0 1 2 3 4 5 6 M H Z X SPACE ENTER see MAIN/TEST.ASM

NEXTSID.INC is the include file for the following v0.5b bins;

VOL-SID.BIN - 4096 BYTES ORG 32768 $8000 **KEEP IN THIS ORDER**
NEXTSID.BIN - 4096 BYTES ORG 36864 $9000 **KEEP IN THIS ORDER**

CTC-SID.BIN - 1152 BYTES ORG 63232 $F700 **DO NOT BANK OUT**

The waveform pattern data is now in the range of 1-128 using a 4K table (VOL-SID.BIN) to scale the volume. A duty cycle value of 0 will cause the engine to calculate undefined results and > 128 will clip.

Changing the table will change the tone of NextSID's signature sound!

NextSID uses around 9-15% CPU @ 28Mhz depending on PT3/channel allocation.

All of the API functions are within CTC-SID.BIN so you don't need to bank in the main core as the API handles the banking and restores the MMU on exit.

CTC-SID.BIN can sit in any MM7 bank8k as long as it is never banked out while interrupts are enabled. The default would be bank8k 1.

Set the 8K core bank when you call nextsid_reset. The core can be any bank8k within the SRAM other than bank8k 1, as it would over-write the API lol. Note, the original init routine has been renamed to nextsid_reset and DE now accepts -1 to use the internal vsync.

ld	de,-1		; LINE (-1 = use NextSID)
ld	bc,192		; Vsync line
ld	a,4		; NextSID bank8k core
call	nextsid_reset	; Init sound engine

16K is allocated for the PT3 file. The bank8ks can be anywhere in the SRAM and also out of order. The interrupt uses MMU5 and MMU6 to bank in the PT3 during init and play, but you don't need to worry as it is all done for you by the API.

DE should be set to the offset within the 16K, NOT an absolute ORG!

ld	de,0		; PT3 offset within the 16K
ld	l,5		; Bank8k a 1st 8K
ld	h,0		; Bank8k b 2nd 8K
call	nextsid_set_pt3	; Stops playback to init new song
call	nextsid_play	; Start playback

The player API will handle waveform patterns of 1-32. 0 is illegal and > 32 will cause a buffer overflow and wipe code/data.

The waveform size is now the actual size of the pattern and NOT -1 as before.

A note about the waveform buffers. They may be banked out depending on your a and b banking configuration for the PT3 song data. It is okay to store the waveform patterns in the same bank8ks you defined for your PT3 song data (if there is enough room). Ask me if you need help!

ld	hl,test_waveform
ld	a,8
call	nextsid_set_waveform_A
call	nextsid_set_waveform_B
call	nextsid_set_waveform_C

The shift BYTE is same as previous, 3 is default.

ld	a,3
ld	(nextsid_shift_B),a

The Detune WORD is a signed 16-bit value per channal as before.

ld	hl,0
ld	(nextsid_detune_B),hl

nextsid_mode control BYTE has changed...

bit 7 is PLAY/STOP (stop acts as pause) bits 6-4 are for PSG C,B,A enable (0 will mute the channel) bits 2-0 are for SID C,B,A enable BUT you must also set the master PSG bit

SID_OFF	equ	00h	; SID enable channel masks
SID_A	equ	01h
SID_B	equ	02h
SID_AB	equ	03h
SID_C	equ	04h
SID_AC	equ	05h
SID_BC	equ	06h
SID_ABC	equ	07h

PSG_OFF	equ	00h	; PSG/SID enable channel masks
PSG_A	equ	10h
PSG_B	equ	20h
PSG_AB	equ	30h
PSG_C	equ	40h
PSG_AC	equ	50h
PSG_BC	equ	60h
PSG_ABC	equ	70h

PT3_PLAY	equ	80h	; PT3 play/stop control
PT3_STOP	equ	00h

ld	a,PSG_ABC+SID_B	; Enable PSG ABC + SID for channel B
ld	(nextsid_mode),a

The following API functions are provided to set the PSG clock and waveform pointer/size;

nextsid_set_psg_clock_A
nextsid_set_psg_clock_B
nextsid_set_psg_clock_C

nextsid_set_waveform_A
nextsid_set_waveform_B
nextsid_set_waveform_C

This is because direct write access to the variables could result in out of order reads by the timer code.

You could wrap your own code with DI/EI if you prefer to write directly to the follow sets of variables. Reading the variables does not require DI/EI.

nextsid_set_waveform_A:

di
ld	(nextsid_wavelen_A),a
ld	(nextsid_waveptr_A),hl
ei
ret

nextsid_set_psg_clock_A:

di
ld	(nextsid_psg_clock_msb_A),de
ld	(nextsid_psg_clock_lsb_A),bc
ei
ret

The RAW AY registers from VT1-MFX are at the following address;

ayregs equ 0xF7D7 ; 14 BYTES VT1-MFX AY registers

See ASM\TEST.ASM for example code.

Two last notes... the timer code uses a table to patch instructions, so changes may be a headache to apply. Some code and data is 256 BYTE aligned.

I have provided an updated demo app using the reference v0.5b player code;

NextSIDi (v0.5b).NEX

Various improvements to scopes, duty cycle edit, detune middle mouse button reset 0 and other fixes. Use left/right mouse buttons/cursor keys to operate. Ships with 19 built-in PT3 files. Will gain a file browser at some point ;)

Allows waveform patterns of 2,3,4,5,6,7,8,12,16,32. Odd pattern sizes will produce some funky harmonics!

Compatible with 1MB ZX Spectrum Nexts.

Finally, a massive thank you to em00k for inspiring me to create this fun project and respect to the developers of the VT1-MFX player and the composers of the PT3 tracks :) I would also like to thank Allen for adding CTC timers to Spectrum Next core.

9bitcolor, June 2021