diff --git a/jopl.c b/jopl.c index f36fe75..591727e 100755 --- a/jopl.c +++ b/jopl.c @@ -49,6 +49,10 @@ void f_keyWasPressed() { consumeKey(k); } +void f_keydown() { + TOP().i = keyIsDown(TOP().i); +} + void do_repl() { char buf[128]; @@ -66,6 +70,7 @@ void do_repl() { CDEF("key-end", kbd_cleanup); CDEF("key-debounce", kbd_debounce); CDEF("key-pressed", f_keyWasPressed); + CDEF("key-down", f_keydown); f_loadfile("jopl.jor"); ontick = f_lookupcp("ontick"); timer_setcallback(timer_callback); diff --git a/jopl.exe b/jopl.exe index e7ebe61..dc2eab2 100755 Binary files a/jopl.exe and b/jopl.exe differ diff --git a/jopl.jor b/jopl.jor index 2f6c6b4..d8e8df4 100755 --- a/jopl.jor +++ b/jopl.jor @@ -9,9 +9,11 @@ REPL start-repl var voice var op +: +voice! voice @ + 10 % voice ! ; + : op-with-voice voice @ - dup 2 > if 5 + then dup 5 > if 5 + then + dup 2 > if 5 + then + op @ + ; : opreg create b, does> ub@ op-with-voice ; : voicereg create b, does> ub@ voice @ + ; @@ -90,11 +92,12 @@ var songticks var notestate var octave +: oct+ octave @ 12 * + ; : rest songticks @ begin dup songticks @ != until drop ; : beat begin dup songticks @ swap % 0 != while rest repeat drop ; : %O octave ! ; : %V voice ! ; -: mknote create b, does> ub@ octave @ 12 * + notestate @ if b, else noteon rest then ; +: mknote create b, does> ub@ oct+ notestate @ if b, else noteon rest then ; : %loop 0xfe b, , ; : % notestate @ if 0xf0 b, else rest then ; : %% 0 for % next ; @@ -132,7 +135,7 @@ array tracks 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , : shush 0 voice @ track ! %- ; : player - songticks @ 1 + songticks ! + 1 songticks +! voice @ 0 10 for i voice ! i track-tick next voice ! ; @@ -155,17 +158,43 @@ var t2 |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 ; -: keyboard - key-start begin +: onkeynote ( cp -- ) keynote dup if oct+ swap execute else drop drop then ; + +: dokeys ( cp -- ) + r> key-start begin key-debounce 1 key-pressed not while - keynote dup if octave @ 12 * + noteon else drop then 78 key-pressed if 1 octave +! then 74 key-pressed if -1 octave +! then - 41 key-pressed if noteoff then + 75 key-pressed if -1 +voice! then + 77 key-pressed if 1 +voice! then + r@ execute rest - repeat key-end ; + 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 ; :noname - default + 9 -1 for i voice ! default next startt2 ; ' onload redefine diff --git a/jopl.prj b/jopl.prj index 8b08d4c..7624429 100755 Binary files a/jopl.prj and b/jopl.prj differ diff --git a/kbd.c b/kbd.c index cf246fd..d0c4088 100755 --- a/kbd.c +++ b/kbd.c @@ -18,12 +18,13 @@ static void interrupt kbd_isr() { unsigned char raw; char ctl; - asm sti; + disable(); + *((int far*)MK_FP(0xb800, 0)) = 0x0165; + raw = inp(0x60); ctl = inp(0x61) | 0x82; outp(0x61, ctl); outp(0x61, ctl & 0x7f); - outp(0x20, 0x20); if (raw & 0x80) { keybuf[raw & 0x7f] &= ~KEY_SIGNAL; @@ -31,6 +32,9 @@ static void interrupt kbd_isr() { keybuf[raw] |= KEY_SIGNAL; } kbd_triggered = raw; + outp(0x20, 0x20); + enable(); + *((int far*)MK_FP(0xb800, 0)) = 0x0166 + (raw % 4); } unsigned char kbd_wait() { @@ -50,7 +54,8 @@ void kbd_init() { void kbd_debounce() { int i = 0; - asm cli; + + disable(); for (i = 0; i < 128; i ++) { unsigned char signal = keybuf[i] & KEY_SIGNAL; unsigned char keystate = keybuf[i] & 0x0f; @@ -71,5 +76,5 @@ void kbd_debounce() { keybuf[i] = signal | keystate; } - asm sti; + enable(); } \ No newline at end of file diff --git a/timer.c b/timer.c index ff58f76..f52856e 100755 --- a/timer.c +++ b/timer.c @@ -12,9 +12,14 @@ static void interrupt (*oldTimerISR)() = NULL; static void (*callback)() = NULL; static void interrupt timer_isr() { + disable(); + *((int far*)MK_FP(0xb800, 2)) = 0x0165; timer_counter ++; if (callback) callback(); + enable(); + *((int far*)MK_FP(0xb800, 2)) = 0x0166; oldTimerISR(); + *((int far*)MK_FP(0xb800, 2)) = 0x0167; } void timer_setcallback(void (*cb)()) {