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