reworked assigner note on
This commit is contained in:
parent
72fa8a2aab
commit
3e16f5314f
@ -2,6 +2,8 @@
|
||||
|
||||
#include "cpuboard.hpp"
|
||||
|
||||
// startup needs to clear RAM etc
|
||||
// 0xffbe = 0x0c; transpose = 12;
|
||||
// Disassembly of assigner.bin, 8192 bytes [0x0 to 0x1fff]
|
||||
// ; start
|
||||
// 0000: 4e 9a JRE $009C
|
||||
@ -20,7 +22,7 @@
|
||||
// 000a: 04 08 10 LXI SP,$1008
|
||||
// 000d: 20 40 INRW $0040
|
||||
// 000f: 80 CALT ($0080)
|
||||
//
|
||||
|
||||
// ; bit patterns used for Note Off
|
||||
// ; ANDed with a flag byte to mask it off
|
||||
// 0010: fe JR $000F
|
||||
@ -30,7 +32,7 @@
|
||||
// 0014: ef JR $0004
|
||||
// 0015: df JR $0035
|
||||
// 0016: bf 7f STAX (HL+$7F)
|
||||
//
|
||||
|
||||
// ; timer/event
|
||||
// 0018: 00 NOP
|
||||
// 0019: 00 NOP
|
||||
@ -873,7 +875,7 @@
|
||||
// 0592: 11 EXX
|
||||
// 0593: aa EI
|
||||
// 0594: 62 RETI
|
||||
//
|
||||
|
||||
// ; serial interrupt handler
|
||||
// 0595: 10 EXA
|
||||
// 0596: 11 EXX
|
||||
@ -910,7 +912,7 @@
|
||||
// 05d5: 75 a0 00 EQIW $00A0,$00
|
||||
// 05d8: 71 a0 80 MVIW $00A0,$80
|
||||
// 05db: d3 JR $05EF ; return from interrupt
|
||||
//
|
||||
|
||||
// ; handle control change
|
||||
// 05dc: 1b MOV C,A
|
||||
// 05dd: 0a MOV A,B
|
||||
@ -927,7 +929,7 @@
|
||||
// 05f0: 11 EXX
|
||||
// 05f1: aa EI
|
||||
// 05f2: 62 RETI
|
||||
//
|
||||
|
||||
// ; wasn't control or note
|
||||
// 05f3: 67 c0 NEI A,$C0 ; program change?
|
||||
// 05f5: c4 JR $05FA
|
||||
@ -1050,53 +1052,111 @@
|
||||
//
|
||||
// ; handle note on/off?
|
||||
// ; called with status in $ff4e, value in $ff3e and velocity in C
|
||||
|
||||
void Assigner::noteOn(uint8_t c) {
|
||||
// 06ca: 01 3e LDAW $003E ; first byte
|
||||
a = ram[0x3e];
|
||||
h06cc:
|
||||
// 06cc: 27 17 GTI A,$17 ; greater than 23
|
||||
// 06ce: 4e 36 JRE $0706 ; no, add an octave
|
||||
if (a > 0x17) {
|
||||
// skip
|
||||
} else
|
||||
goto h0706;
|
||||
h06d0:
|
||||
// 06d0: 37 6d LTI A,$6D ; less than 108
|
||||
// 06d2: 4e 36 JRE $070A ; no, subtract an octave
|
||||
if (a < 0x6d) {
|
||||
// skip
|
||||
} else
|
||||
goto h070a;
|
||||
// 06d4: 74 e0 be SUBW $00BE ; subtract a value - transpose?
|
||||
a -= ram[0xbe];
|
||||
// 06d7: 1a MOV B,A ; save in b
|
||||
b = a;
|
||||
// 06d8: 48 22 SLR B
|
||||
// 06da: 48 22 SLR B
|
||||
// 06dc: 48 22 SLR B ; divide by 8
|
||||
b >>= 3;
|
||||
// 06de: 07 07 ANI A,$07 ; lower three bits
|
||||
a &= 0x07;
|
||||
// 06e0: 75 4e 90 EQIW $004E,$90 ; note on?
|
||||
// 06e3: d5 JR $06F9 ; no, jump ahead
|
||||
if (ram[0x4e] == 0x90) {
|
||||
// skip
|
||||
} else
|
||||
goto h06f9;
|
||||
|
||||
// 06e4: 74 6b 00 NEI C,$00 ; velocity 0
|
||||
// 06e7: d1 JR $06F9 ; no, jump ahead
|
||||
if (c != 0) {
|
||||
// skip
|
||||
} else
|
||||
goto h06f9;
|
||||
|
||||
// ; otherwise fall through and handle Note On
|
||||
// 06e8: 34 08 00 LXI HL,$0008 ; lookup table runs 01, 02, 04, 08, 10, 20, 40, 80
|
||||
// ; inverse of the one at 0x0010
|
||||
// 06eb: ac LDAX (HL+A) ; look up table based on note
|
||||
hl = 0x08;
|
||||
a = bitMask[hl + a]; // fetch bit corresponding to lower bits of note
|
||||
|
||||
// 06ec: 1b MOV C,A ; save
|
||||
// 06ed: 34 40 ff LXI HL,$FF40 ; bit flags
|
||||
// 06f0: ad LDAX (HL+B) ; byte pointed to by upper part
|
||||
// 06f1: 60 9b ORA A,C ; or in whichever note is flagged
|
||||
// 06f3: bd STAX (HL+B) ; save in flag
|
||||
//
|
||||
// ;
|
||||
|
||||
c = a; // save A for later
|
||||
hl = 0x40; // MIDI key bitmap
|
||||
a = ram[hl + b];
|
||||
a |= c;
|
||||
ram[hl + b] = a; // OR in the bit we saved and save it back
|
||||
|
||||
// ; this sets up the MIDI routine to expect a two-byte message again
|
||||
// which allows for running status
|
||||
// 06f4: 71 3f 01 MVIW $003F,$01 ; expect two bytes
|
||||
// 06f7: 4f 53 JRE $064C ; return
|
||||
//
|
||||
return;
|
||||
|
||||
h06f9:
|
||||
// ; note off?
|
||||
// ; A contains lower three bits of note, B contains upper 4 bits
|
||||
// 06f9: 34 10 00 LXI HL,$0010 ; lookup table runs fe, fd, fb, f7, ef, df, bf, 7f
|
||||
// ; inverse of 0x0008
|
||||
// 06fc: ac LDAX (HL+A) ; look up the table based on the note
|
||||
hl = 0x10;
|
||||
a = bitMask[hl + a];
|
||||
|
||||
// 06fd: 1b MOV C,A ; fetch value, store in C
|
||||
// 06fe: 34 40 ff LXI HL,$FF40 ; table in RAM
|
||||
// 0701: ad LDAX (HL+B) ; $FF40 + upper four bits as offset
|
||||
// 0702: 60 8b ANA A,C ; mask off the bit for the note
|
||||
// 0704: bd STAX (HL+B) ; store at $FF40 + offset
|
||||
|
||||
c = a;
|
||||
hl = 0x40;
|
||||
a = ram[hl + b];
|
||||
a &= c;
|
||||
ram[hl + b] = a;
|
||||
return;
|
||||
|
||||
// jump back to set up for running status
|
||||
// 0705: ee JR $06F4
|
||||
//
|
||||
|
||||
h0706:
|
||||
// ; add or subtract an octave to bring out-of-range notes in
|
||||
// 0706: 46 0c ADI A,$0C ; add 12 to note value in A
|
||||
// 0708: 4f c2 JRE $06CC ; jump back and test if it's in range yet
|
||||
a += 12; // semitones
|
||||
goto h06cc; // test again
|
||||
|
||||
h070a:
|
||||
// 070a: 66 0c SUI A,$0C ; subtract 12 from note value in A
|
||||
// 070c: 4f c2 JRE $06D0 ; jump back and test if it's in range yet
|
||||
//
|
||||
a -= 12; // semitones
|
||||
goto h06d0;
|
||||
|
||||
// ; store first value
|
||||
// 070e: 63 3e STAW $003E
|
||||
// 0710: 4f 3a JRE $064C ; return from interrupt
|
||||
@ -1185,7 +1245,7 @@
|
||||
// 07a8: 4f 4a JRE $06F4 ; return, two byte running status
|
||||
// 07aa: 71 a1 80 MVIW $00A1,$80 ; reset bend?
|
||||
// 07ad: 4f 45 JRE $06F4 ; return, two byte running status
|
||||
//
|
||||
}
|
||||
// ; handle TX interrupt
|
||||
// 07af: 01 c1 LDAW $00C1 ; buffer pointers?
|
||||
// 07b1: 74 f8 c2 EQAW $00C2
|
||||
|
@ -71,14 +71,16 @@ void Chassis::noteOn(uint8_t note) {
|
||||
|
||||
ic1.ram[0x4e] = 0x90;
|
||||
ic1.ram[0x3e] = note;
|
||||
ic1.noteOn();
|
||||
ic1.noteOn(0x40);
|
||||
|
||||
/*
|
||||
#ifdef D_MIDIBITMAP
|
||||
printf("note on -> ");
|
||||
for (uint8_t i = 0x40; i < 0x4f; i++) {
|
||||
printf("%02x ", ic1.ram[i]);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
#endif
|
||||
|
||||
s.keyon = true;
|
||||
for (i = 0; i < NUM_VOICES; i++) {
|
||||
vPtr++;
|
||||
@ -98,16 +100,18 @@ void Chassis::noteOn(uint8_t note) {
|
||||
}
|
||||
|
||||
void Chassis::noteOff(uint8_t note) {
|
||||
ic1.ram[0x4e] = 0x80;
|
||||
ic1.ram[0x4e] = 0x90;
|
||||
ic1.ram[0x3e] = note;
|
||||
ic1.noteOn();
|
||||
ic1.noteOn(0);
|
||||
|
||||
/*
|
||||
#ifdef D_MIDIBITMAP
|
||||
printf("note off -> ");
|
||||
for (uint8_t i = 0x40; i < 0x4f; i++) {
|
||||
printf("%02x ", ic1.ram[i]);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
#endif
|
||||
|
||||
s.keyon = false;
|
||||
for (uint32_t i = 0; i < NUM_VOICES; i++) {
|
||||
if (s.voice[i].note == note && !s.voice[i].isFree()) {
|
||||
@ -133,7 +137,7 @@ void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) {
|
||||
}
|
||||
lastEvent = i;
|
||||
|
||||
ic1.voiceOn();
|
||||
//ic1.voiceOn();
|
||||
}
|
||||
|
||||
void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEvent *midiEvents, uint32_t midiEventCount) {
|
||||
|
@ -2,16 +2,23 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#define D_MIDIBITMAP
|
||||
|
||||
class Assigner {
|
||||
public:
|
||||
uint8_t ram[256];
|
||||
uint16_t a = 0, b = 0, c = 0, eal = 0, eah = 0;
|
||||
uint32_t bc, de, hl, ea = 0;
|
||||
|
||||
void noteOn();
|
||||
void noteOn(uint8_t c);
|
||||
void voiceOn();
|
||||
void resetVoices();
|
||||
// void clearNotes();
|
||||
// void assignNote();
|
||||
|
||||
private:
|
||||
uint8_t bitMask[24] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
|
||||
};
|
Loading…
Reference in New Issue
Block a user