indirect voice access

This commit is contained in:
2026-01-14 19:05:14 +00:00
parent d06e5c404c
commit b83d5400f9
2 changed files with 162 additions and 18 deletions

36
sid-hl.4th Normal file
View File

@@ -0,0 +1,36 @@
( PS2! c c p-addr -- Data byte A, high address byte B, port address C - OUT to port with A and B registers set
: PC2! SWAP >< OR PC! ;
( SID! c c -- Data value, register 0-31; bits 5,6 are for interrupt settings; bit 7 /CS is handled
: SID!
2DUP 128 OR 84 PC2!
2DUP 127 AND 84 PC2!
128 OR 84 PC2! ;
( Voice control register flags
: SID:CTL:GATE 1 ;
: SID:CTL:SYNC 2 ;
: SID:CTL:RING 4 ;
: SID:CTL:TEST 8 ;
: SID:CTL:TRI 16 ;
: SID:CTL:SAW 32 ;
: SID:CTL:PWM 64 ;
: SID:CTL:NOISE 128 ;
( Frequency table:
: SID:NOTE:C4 4389 ;
: SID:NOTE:C4# 4650 ;
: SID:NOTE:D4 4927 ;
: SID:NOTE:D4# 5220 ;
: SID:NOTE:E4 5530 ;
: SID:NOTE:F4 5859 ;
: SID:NOTE:F4# 6207 ;
: SID:NOTE:G4 6577 ;
: SID:NOTE:G4# 6968 ;
: SID:NOTE:A4 7382 ;
: SID:NOTE:A4# 7821 ;
: SID:NOTE:B4 8286 ;
( Octave shifts
: SID:OCT:UP 2* ;
: SID:OCT:DOWN 2/ ;
: SID:VOICE ( n -- )

144
sid.4th
View File

@@ -1,3 +1,5 @@
(--- SID chip access ---)
: PC2! ( c c p-addr -- Data byte A, high address byte B, port address C - OUT to port with A and B registers set )
SWAP >< OR PC! ;
: SID! ( c c -- Data value, register 0-31; bits 5,6 are for interrupt settings; bit 7 /CS is handled )
@@ -5,7 +7,8 @@
2DUP 127 AND 84 PC2!
128 OR 84 PC2! ;
( -- n Voice control register flags )
(--- SID chip control register flags ---)
: SID:CTL:GATE 1 ;
: SID:CTL:SYNC 2 ;
: SID:CTL:RING 4 ;
@@ -15,6 +18,27 @@
: SID:CTL:PWM 64 ;
: SID:CTL:NOISE 128 ;
(--- Frequency table ---)
: SID:NOTE:C4 4389 ;
: SID:NOTE:C4# 4650 ;
: SID:NOTE:D4 4927 ;
: SID:NOTE:D4# 5220 ;
: SID:NOTE:E4 5530 ;
: SID:NOTE:F4 5859 ;
: SID:NOTE:F4# 6207 ;
: SID:NOTE:G4 6577 ;
: SID:NOTE:G4# 6968 ;
: SID:NOTE:A4 7382 ;
: SID:NOTE:A4# 7821 ;
: SID:NOTE:B4 8286 ;
( Octave shifts )
: SID:OCT:UP 2* ;
: SID:OCT:DOWN 2/ ;
(--- Direct access ---)
( Voice 1 )
: SID0/1:FREQ! ( n -- Reg 0,1 - frequency voice 1 )
DUP 255 AND 0 SID! >< 255 AND 1 SID! ;
@@ -78,23 +102,6 @@
1024 SID21/22:CUT! 10 SID23:RES SID23!
15 SID24:VOL SID24! ;
( -- n Frequency table: )
: SID:NOTE:C4 4389 ;
: SID:NOTE:C4# 4650 ;
: SID:NOTE:D4 4927 ;
: SID:NOTE:D4# 5220 ;
: SID:NOTE:E4 5530 ;
: SID:NOTE:F4 5859 ;
: SID:NOTE:F4# 6207 ;
: SID:NOTE:G4 6577 ;
: SID:NOTE:G4# 6968 ;
: SID:NOTE:A4 7382 ;
: SID:NOTE:A4# 7821 ;
: SID:NOTE:B4 8286 ;
( n -- n Octave shifts )
: SID:OCT:UP 2* ;
: SID:OCT:DOWN 2/ ;
( Voice contorl registers )
VARIABLE SID:V1:CTL
: SID:V1:CTL! ( c -- Set CTL register for voice 1 )
@@ -188,3 +195,104 @@ SID:TEST:MELODY
SID:TEST:FILTER
SID:TEST:SONG
(--- Voice selection ---)
CREATE SID:VOICE-BASES 0 , 7 , 14 , ( 3'base )
CREATE SID:VOICE-CTLS 0 , 0 , 0 , ( 3clt-reg-shadow )
: SID:VOICE-BASE-ADDR ( voice -- 'reg-no )
CELL * SID:VOICE-BASES + ;
: SID:VOICE-CTL-ADDR ( voice -- 'ctl-addr )
CELL * SID:VOICE-CTLS + ;
CREATE SID:VOICE-BASE-PTR SID:VOICE-BASES ,
CREATE SID:VOICE-CTL-PTR SID:VOICE-CTLS ,
: SID:SELECT-VOICE ( voice -- ) ( select SELECT voice )
DUP
SID:VOICE-BASE-ADDR SID:VOICE-BASE-PTR !
SID:VOICE-CTL-ADDR SID:VOICE-CTL-PTR ! ;
: SID:VOICE-REG-NO ( -- n ) ( Base SID register number for selected voice )
SID:VOICE-BASE-PTR @ @ ;
(--- Voice register ops ---)
: SID:VOICE! ( c n -- ) ( Store byte in selected voice register n )
SID:VOICE-REG-NO + SID! ;
: SID:VOICE-CTL ( -- a-addr ) ( Control register shadow for current voice )
SID:VOICE-CTL-PTR @ ;
: SID:VOICE-FREQ! ( n -- ) ( Reg 0,1 - Set frequency )
DUP 255 AND 0 SID:VOICE! >< 255 AND 1 SID:VOICE! ;
: SID:VOICE-PWM! ( n -- ) ( Reg 2,3 - Set pulse wave duty cycle )
DUP 255 AND 2 SID:VOICE! >< 15 AND 3 SID:VOICE! ;
: SID:VOICE-CTL! ( c -- ) ( Reg 4 - Set control register; write-through shadow )
DUP SID:VOICE-CTL ! 4 SID:VOICE! ;
: SID:VOICE-ATK/DEC! ( c -- ) ( Reg 5 - Set attack duration / decay duration )
15 AND SWAP 4 LSHIFT OR 5 SID:VOICE! ;
: SID:VOICE-SUS/REL! ( c -- ) ( Reg 6 - Set sustain level / release duration )
15 AND SWAP 4 LSHIFT OR 6 SID:VOICE! ;
: SID:VOICE-PLAY ( freq -- ) ( Start note at given frequency )
SID:VOICE-FREQ! SID:VOICE-CTL @ SID:CTL:GATE OR 4 SID:VOICE! ;
: SID:VOICE-STOP ( -- ) ( Stop note )
SID:VOICE-CTL @ SID:CTL:GATE INVERT AND 4 SID:VOICE! ;
(--- Other registers ---)
: SID:CUTOFF! ( n -- ) ( Reg 21/22 - Set filter cutoff frequency 0 - 2047 / 11 bits )
DUP 7 AND 21 SID! 3 RSHIFT 255 AND 22 SID! ;
( Reg 23 - filter resonance 0 - 15 / 4 bits, ext, voice 3, voice 2, voice 1 )
: SID:FILTER:RES 15 AND 4 LSHIFT ;
: SID:FILTER:V1 1 OR ;
: SID:FILTER:V2 2 OR ;
: SID:FILTER:V3 4 OR ;
: SID:EXT 8 OR ;
: SID:FILTER-RES-FLAGS!
23 SID! ;
( Reg 24 - filter mode and main volume control )
: SID:VOLUME 15 AND ;
: SID:FILTER:LOWPASS 16 OR ;
: SID:FILTER:BANDPASS 32 OR ;
: SID:FILTER:HIGHPASS 64 OR ;
: SID:MUTEVOICE3 128 OR ;
: SID:VOL-FILTER!
24 SID! ;
(--- Reset ---)
: SID:VOICE-RST ( -- ) ( Reset selected voice state )
SID:NOTE:C4 SID:VOICE-FREQ!
2048 SID:VOICE-PWM!
0 SID:VOICE-CTL!
4 2 SID:VOICE-ATK/DEC!
10 9 SID:VOICE-SUS/REL! ;
: SID:OTHER-RST
1024 SID:CUTOFF!
10 SID:FILTER:RES SID:FILTER-RES-FLAGS!
15 SID:VOLUME SID:VOL-FILTER! ;
: SID:RST ( Full SID chip reset )
2 SID:SELECT-VOICE SID:VOICE-RST
1 SID:SELECT-VOICE SID:VOICE-RST
0 SID:SELECT-VOICE SID:VOICE-RST
SID:OTHER-RST ;
(--- Test ---)
: DELAY 10000 0 DO LOOP ;
: SID:TEST:NOTE
SID:NOTE:C4 SID:VOICE-PLAY
DELAY DELAY
SID:VOICE-STOP ;
SID:RST
SID:CTL:TRI SID:VOICE-CTL! ( Select triangle waveform )
SID:TEST:NOTE