2019-03-31 23:29:16 +00:00
|
|
|
' putc task-emit !
|
2019-04-13 14:30:36 +00:00
|
|
|
s" jopl.log" open seekend fdeactivate const LOGFILE
|
|
|
|
: emit-log fdeactivate LOGFILE factivate fputc fdeactivate drop factivate ;
|
|
|
|
: quit LOGFILE factivate close _quit ;
|
2019-03-31 23:29:16 +00:00
|
|
|
|
2019-04-13 14:30:36 +00:00
|
|
|
: start-repl activate
|
|
|
|
' putc task-emit ! ' emit-log task-echo !
|
2019-03-31 23:29:16 +00:00
|
|
|
s" .:: J O P L ( jean OPL2 print loop) ::." type cr
|
|
|
|
begin receive loadstring s" ok" type cr again ;
|
|
|
|
task const REPL
|
|
|
|
REPL start-repl
|
|
|
|
|
|
|
|
var voice
|
|
|
|
var op
|
|
|
|
|
2019-04-05 23:35:43 +00:00
|
|
|
: +voice! voice @ + 10 % voice ! ;
|
|
|
|
|
2019-03-31 23:29:16 +00:00
|
|
|
: op-with-voice voice @
|
|
|
|
dup 5 > if 5 + then
|
2019-04-05 23:35:43 +00:00
|
|
|
dup 2 > if 5 + then
|
2019-03-31 23:29:16 +00:00
|
|
|
+ op @ + ;
|
|
|
|
: opreg create b, does> ub@ op-with-voice ;
|
|
|
|
: voicereg create b, does> ub@ voice @ + ;
|
|
|
|
|
|
|
|
0x20 opreg ar-flags
|
|
|
|
0x40 opreg ar-level
|
|
|
|
0x60 opreg ar-ad
|
|
|
|
0x80 opreg ar-sr
|
|
|
|
0xe0 opreg ar-wave
|
|
|
|
0xc0 voicereg ar-alg
|
|
|
|
|
|
|
|
0xa0 voicereg ar-freq
|
|
|
|
0xb0 voicereg ar-note
|
|
|
|
|
|
|
|
: op2 3 op ! ;
|
|
|
|
: op1 0 op ! ;
|
|
|
|
: loadop ( flags level ad sr wave -- )
|
|
|
|
ar-wave adlib!
|
|
|
|
ar-sr adlib!
|
|
|
|
ar-ad adlib!
|
|
|
|
ar-level adlib!
|
|
|
|
ar-flags adlib! ;
|
|
|
|
|
|
|
|
: readop ( v -- )
|
|
|
|
r> r@ 4 + b@ r@ 3 + b@ r@ 2 + b@ r@ 1 + b@ r< b@ loadop ;
|
|
|
|
|
|
|
|
: instrument ( alg f1 l1 ad1 sr1 w1 f2 l2 ad2 sr2 w2 -- )
|
|
|
|
create b, b, b, b, b, b, b, b, b, b, b, does>
|
|
|
|
dup dup 5 + op1 readop op2 readop
|
|
|
|
10 + b@ ar-alg adlib! ;
|
|
|
|
|
|
|
|
0 0x01 0x10 0xf0 0x77 0 0x01 0x00 0xf0 0x77 0 instrument default
|
|
|
|
|
|
|
|
: freqon ( oct freq -- )
|
|
|
|
dup 0xff & ar-freq adlib!
|
|
|
|
8 >> 0x03 & swap 2 << | 0x20 | ar-note adlib! ;
|
|
|
|
: noteoff ( -- ) 0 ar-note adlib! ;
|
|
|
|
|
|
|
|
array semitones
|
|
|
|
3520 3520 />ratio ,
|
|
|
|
3729 3520 />ratio ,
|
|
|
|
3951 3520 />ratio ,
|
|
|
|
4186 3520 />ratio ,
|
|
|
|
4435 3520 />ratio ,
|
|
|
|
4699 3520 />ratio ,
|
|
|
|
4978 3520 />ratio ,
|
|
|
|
5274 3520 />ratio ,
|
|
|
|
5588 3520 />ratio ,
|
|
|
|
5920 3520 />ratio ,
|
|
|
|
6272 3520 />ratio ,
|
|
|
|
6645 3520 />ratio ,
|
|
|
|
|
|
|
|
: note dup 12 / 8 % swap 12 % cells semitones + @ 440 swap *<ratio ;
|
|
|
|
: noteon noteoff note freqon ;
|
|
|
|
|
|
|
|
: read-sbi-reg ( reg-cp -- )
|
|
|
|
fgetc swap execute adlib! ;
|
|
|
|
|
|
|
|
: read-sbi-op-reg ( reg-cp -- )
|
|
|
|
dup op1 read-sbi-reg
|
|
|
|
op2 read-sbi-reg ;
|
|
|
|
|
|
|
|
: loadsbi ( filename -- )
|
|
|
|
open 36 seek
|
|
|
|
' ar-flags read-sbi-op-reg
|
|
|
|
' ar-level read-sbi-op-reg
|
|
|
|
' ar-ad read-sbi-op-reg
|
|
|
|
' ar-sr read-sbi-op-reg
|
|
|
|
' ar-wave read-sbi-op-reg
|
|
|
|
fgetc ar-alg adlib!
|
|
|
|
close ;
|
|
|
|
|
|
|
|
: panic 9 -1 for i voice ! noteoff next ;
|
|
|
|
|
|
|
|
var songticks
|
|
|
|
|
|
|
|
var notestate
|
|
|
|
var octave
|
2019-04-05 23:35:43 +00:00
|
|
|
: oct+ octave @ 12 * + ;
|
2019-03-31 23:29:16 +00:00
|
|
|
: rest songticks @ begin dup songticks @ != until drop ;
|
|
|
|
: beat begin dup songticks @ swap % 0 != while rest repeat drop ;
|
|
|
|
: %O octave ! ;
|
|
|
|
: %V voice ! ;
|
2019-04-05 23:35:43 +00:00
|
|
|
: mknote create b, does> ub@ oct+ notestate @ if b, else noteon rest then ;
|
2019-03-31 23:29:16 +00:00
|
|
|
: %loop 0xfe b, , ;
|
2019-04-10 02:00:32 +00:00
|
|
|
: mod % ;
|
2019-03-31 23:29:16 +00:00
|
|
|
: % notestate @ if 0xf0 b, else rest then ;
|
|
|
|
: %% 0 for % next ;
|
|
|
|
: %- notestate @ if 0xfd b, else noteoff then ;
|
|
|
|
: %do 0xff b, , ;
|
2019-04-13 14:30:36 +00:00
|
|
|
|
2019-03-31 23:29:16 +00:00
|
|
|
11 mknote G#
|
2019-04-13 14:30:36 +00:00
|
|
|
10 mknote G
|
|
|
|
9 mknote F#
|
|
|
|
8 mknote F
|
|
|
|
7 mknote E
|
|
|
|
6 mknote D#
|
|
|
|
5 mknote D
|
|
|
|
4 mknote C#
|
|
|
|
3 mknote C
|
|
|
|
2 mknote B
|
|
|
|
1 mknote A#
|
|
|
|
0 mknote A
|
2019-03-31 23:29:16 +00:00
|
|
|
|
|
|
|
array tracks 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
|
|
|
|
|
|
|
: track ( i -- p ) cells tracks + ;
|
|
|
|
: dotrack ( ip -- ip )
|
|
|
|
dup if dup 1 + swap ub@ r>
|
|
|
|
r@ 0xff = if dup @ swap cell + swap execute then
|
|
|
|
r@ 0xfe = if @ dotrack then
|
|
|
|
r@ 0xfd = if noteoff then
|
|
|
|
r@ 0xf0 < if r@ noteon then
|
|
|
|
rdrop then ;
|
|
|
|
|
|
|
|
: track-tick ( i -- )
|
|
|
|
track dup @ dotrack swap ! ;
|
|
|
|
|
|
|
|
: :track create here 1 notestate ! does> voice @ track ! ;
|
|
|
|
: ;track %loop 0 notestate ! ;
|
|
|
|
: shush 0 voice @ track ! %- ;
|
|
|
|
|
2019-04-13 14:30:36 +00:00
|
|
|
: prev-name ( wordname -- wordname )
|
|
|
|
2 cells - @ 2 cells + ;
|
|
|
|
: 'name [ ' [ , ' ' , ' ] , ] ` lit ; immediate
|
|
|
|
|
|
|
|
: emit-octave ( note -- )
|
|
|
|
12 / dup octave @ != if dup octave ! . s" %O " type else drop then ;
|
|
|
|
|
|
|
|
: emit-note ( note -- )
|
|
|
|
'name A swap 12 mod 0 for prev-name next type bl ;
|
|
|
|
|
|
|
|
: emit-cmd ( cmd -- more )
|
|
|
|
dup 0xf0 = if s" % " type then
|
|
|
|
dup 0xfd = if s" %- " type then
|
|
|
|
dup 0xf0 < if dup emit-octave emit-note 1 then
|
|
|
|
dup 0xfe = if 'name ;track type cr drop 0 then ;
|
|
|
|
|
|
|
|
: emit-track ( 'track -- )
|
|
|
|
-1 octave ! dup ` swap 2 cells +
|
|
|
|
'name :track type bl swap type bl
|
|
|
|
begin dup ub@ emit-cmd while 1 + repeat drop ;
|
|
|
|
|
|
|
|
|
2019-04-10 02:00:32 +00:00
|
|
|
var tempo 1 tempo !
|
2019-03-31 23:29:16 +00:00
|
|
|
: player
|
2019-04-05 23:35:43 +00:00
|
|
|
1 songticks +!
|
2019-04-10 02:00:32 +00:00
|
|
|
songticks @ tempo @ mod 0 = if
|
|
|
|
voice @
|
|
|
|
0 10 for i voice ! i track-tick next
|
|
|
|
voice !
|
|
|
|
then ;
|
2019-03-31 23:29:16 +00:00
|
|
|
|
|
|
|
var t2
|
|
|
|
: startt2
|
|
|
|
0x60 0x04 adlib!
|
|
|
|
0x80 0x04 adlib!
|
|
|
|
t2 @ 0x03 adlib!
|
|
|
|
0x42 0x04 adlib! ;
|
|
|
|
|
|
|
|
: ontick adlib@ 0x20 & if startt2 player then ;
|
|
|
|
|
2019-04-03 01:52:02 +00:00
|
|
|
: files findfile begin dup while yield findnext repeat ;
|
|
|
|
|
|
|
|
: keynote [ inline|
|
|
|
|
44 b, 31 b, 45 b, 32 b, 46 b, 47 b, 34 b, 48 b, 35 b, 49 b, 36 b, 50 b,
|
|
|
|
16 b, 3 b, 17 b, 4 b, 18 b, 19 b, 6 b, 20 b, 7 b, 21 b, 8 b, 22 b,
|
|
|
|
23 b, 10 b, 24 b, 11 b, 25 b,
|
|
|
|
|inline ] 0 29 for dup i + ub@ key-pressed if drop i 3 + rdrop rdrop ret then next
|
|
|
|
drop 51 key-pressed if 15 else 0 then ;
|
|
|
|
|
2019-04-05 23:35:43 +00:00
|
|
|
: onkeynote ( cp -- ) keynote dup if oct+ swap execute else drop drop then ;
|
|
|
|
|
|
|
|
: dokeys ( cp -- )
|
|
|
|
r> key-start begin
|
2019-04-03 01:52:02 +00:00
|
|
|
key-debounce 1 key-pressed not while
|
|
|
|
78 key-pressed if 1 octave +! then
|
|
|
|
74 key-pressed if -1 octave +! then
|
2019-04-05 23:35:43 +00:00
|
|
|
75 key-pressed if -1 +voice! then
|
|
|
|
77 key-pressed if 1 +voice! then
|
|
|
|
r@ execute
|
2019-04-03 01:52:02 +00:00
|
|
|
rest
|
2019-04-05 23:35:43 +00:00
|
|
|
repeat key-end rdrop ;
|
|
|
|
|
|
|
|
: nextnote ( ip -- ip )
|
|
|
|
dup if
|
|
|
|
dup ub@ r>
|
|
|
|
r@ 0xff = if drop 0 else
|
|
|
|
r@ 0xfe = if 1 + @ nextnote then then
|
|
|
|
rdrop
|
|
|
|
then ;
|
|
|
|
|
|
|
|
: setnote ( note -- )
|
|
|
|
voice @ track @ nextnote
|
|
|
|
dup if b! else drop drop then ;
|
|
|
|
|
|
|
|
: record
|
|
|
|
:| ' setnote onkeynote
|
|
|
|
41 key-pressed if 0xfd setnote then
|
|
|
|
52 key-down if 0xf0 setnote then
|
|
|
|
|; dokeys ;
|
|
|
|
|
|
|
|
: jam
|
|
|
|
:| ' noteon onkeynote
|
|
|
|
41 key-pressed if noteoff then
|
|
|
|
|; dokeys ;
|
2019-04-03 01:52:02 +00:00
|
|
|
|
2019-03-31 23:29:16 +00:00
|
|
|
:noname
|
2019-04-05 23:35:43 +00:00
|
|
|
9 -1 for i voice ! default next
|
2019-03-31 23:29:16 +00:00
|
|
|
startt2
|
|
|
|
; ' onload redefine
|