Splitted audio device into four

This commit is contained in:
Andrew Alderwick 2021-04-26 19:49:34 +01:00
parent 53329c8eff
commit f90a97386c
5 changed files with 68 additions and 91 deletions

View File

@ -6,8 +6,6 @@
%++ { #0001 ADD2 } %++ { #0001 ADD2 }
%MOD { DUP2 DIV MUL SUB } %MOD { DUP2 DIV MUL SUB }
%TRACK { ;track/ch1 #00 .track/active PEK #0020 MUL2 ADD2 } %TRACK { ;track/ch1 #00 .track/active PEK #0020 MUL2 ADD2 }
%SOUND { STH #00 .Audio/value DEO2 STHr #00 .Audio/delay DEO2 }
%SOUND_FINISH { #00 .Audio/finish DEO }
( variables ) ( variables )
@ -21,15 +19,16 @@
@knob [ &x $2 &y $2 &value $1 ] @knob [ &x $2 &y $2 &value $1 ]
@head [ &pos $1 ] @head [ &pos $1 ]
@track [ &active $1 &ch1 $20 &ch2 $20 &ch3 $20 &ch4 $20 ] @track [ &active $1 &ch1 $20 &ch2 $20 &ch3 $20 &ch4 $20 ]
@adsr [ &ch1 $2 &ch2 $2 &ch3 $2 &ch4 $2 ]
@volume [ &ch1 $1 &ch2 $1 &ch3 $1 &ch4 $1 ]
( devices ) ( devices )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ] |00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|10 @Console [ &vector $2 &pad $6 &char $1 &byte $1 &short $2 &string $2 ] |10 @Console [ &vector $2 &pad $6 &char $1 &byte $1 &short $2 &string $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ] |20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ]
|30 @Audio [ &pad $8 &adsr $2 &len $2 &addr $2 &volume $1 &pitch $1 ] |30 @Audio0 [ &vector $2 &output $1 &pad $5 &adsr $2 &len $2 &addr $2 &volume $1 &pitch $1 ]
|40 @Audio1 [ &vector $2 &output $1 &pad $5 &adsr $2 &len $2 &addr $2 &volume $1 &pitch $1 ]
|50 @Audio2 [ &vector $2 &output $1 &pad $5 &adsr $2 &len $2 &addr $2 &volume $1 &pitch $1 ]
|60 @Audio3 [ &vector $2 &output $1 &pad $5 &adsr $2 &len $2 &addr $2 &volume $1 &pitch $1 ]
|80 @Controller [ &vector $2 &button $1 &key $1 ] |80 @Controller [ &vector $2 &button $1 &key $1 ]
|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &chord $1 ] |90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &chord $1 ]
|a0 @File [ &vector $2 &success $2 &offset $2 &pad $2 &name $2 &length $2 &load $2 &save $2 ] |a0 @File [ &vector $2 &success $2 &offset $2 &pad $2 &name $2 &length $2 &load $2 &save $2 ]
@ -56,12 +55,19 @@
.trkframe/x2 PEK2 .ctlframe/x2 POK2 .chnframe/y2 PEK2 .ctlframe/y2 POK2 .trkframe/x2 PEK2 .ctlframe/x2 POK2 .chnframe/y2 PEK2 .ctlframe/y2 POK2
( default settings ) ( default settings )
#048c .adsr/ch1 POK2 #88 .volume/ch1 POK #048c .Audio0/adsr DEO2 #88 .Audio0/volume DEO
#159d .adsr/ch2 POK2 #88 .volume/ch2 POK #159d .Audio1/adsr DEO2 #88 .Audio1/volume DEO
#26ae .adsr/ch3 POK2 #88 .volume/ch3 POK #26ae .Audio2/adsr DEO2 #88 .Audio2/volume DEO
#260e .adsr/ch4 POK2 #88 .volume/ch4 POK #0000 .Audio3/adsr DEO2 #88 .Audio3/volume DEO
.volume/ch3 PEK .Audio/volume DEO ;square-wave .Audio0/addr DEO2
;square-wave/end ;square-wave SUB2 .Audio0/len DEO2
;triangle-wave .Audio1/addr DEO2
;triangle-wave/end ;triangle-wave SUB2 .Audio1/len DEO2
;sine-wave .Audio2/addr DEO2
;sine-wave/end ;sine-wave SUB2 .Audio2/len DEO2
;noise-wave .Audio3/addr DEO2
;noise-wave-end ;noise-wave SUB2 .Audio3/len DEO2
;draw-timeline JSR2 ;draw-timeline JSR2
;draw-controls JSR2 ;draw-controls JSR2
@ -122,10 +128,7 @@ BRK
@play ( pitch -- ) @play ( pitch -- )
.adsr/ch3 PEK2 .Audio/adsr DEO2 .Audio0/pitch DEO
;triangle-wave .Audio/addr DEO2
;triangle-wave/end ;triangle-wave SUB2 .Audio/len DEO2
.Audio/pitch DEO
RTN RTN
@ -157,29 +160,29 @@ BRK
.Mouse/x DEI2 .ctlframe/x1 PEK2 SUB2 8- 8/ SWP POP #02 DIV .Mouse/x DEI2 .ctlframe/x1 PEK2 SUB2 8- 8/ SWP POP #02 DIV
DUP #00 NEQ ,&no-a JNZ DUP #00 NEQ ,&no-a JNZ
.adsr .track/active PEK #02 MUL ADD PEK .Audio0/adsr .track/active PEK #10 MUL ADD DEI
#10 .Mouse/state DEI #10 EQU #e0 MUL ADD ADD #10 .Mouse/state DEI #10 EQU #e0 MUL ADD ADD
.adsr .track/active PEK #02 MUL ADD POK &no-a .Audio0/adsr .track/active PEK #10 MUL ADD DEO &no-a
DUP #01 NEQ ,&no-d JNZ DUP #01 NEQ ,&no-d JNZ
.adsr .track/active PEK #02 MUL ADD PEK .Audio0/adsr .track/active PEK #10 MUL ADD DEI
DUP #f0 AND STH #01 .Mouse/state DEI #10 EQU #0e MUL ADD ADD #0f AND STHr ADD DUP #f0 AND STH #01 .Mouse/state DEI #10 EQU #0e MUL ADD ADD #0f AND STHr ADD
.adsr .track/active PEK #02 MUL ADD POK &no-d .Audio0/adsr .track/active PEK #10 MUL ADD DEO &no-d
DUP #02 NEQ ,&no-s JNZ DUP #02 NEQ ,&no-s JNZ
.adsr .track/active PEK #02 MUL ADD #01 ADD PEK .Audio0/adsr .track/active PEK #10 MUL ADD #01 ADD DEI
#10 .Mouse/state DEI #10 EQU #e0 MUL ADD ADD #10 .Mouse/state DEI #10 EQU #e0 MUL ADD ADD
.adsr .track/active PEK #02 MUL ADD #01 ADD POK &no-s .Audio0/adsr .track/active PEK #10 MUL ADD #01 ADD DEO &no-s
DUP #03 NEQ ,&no-r JNZ DUP #03 NEQ ,&no-r JNZ
.adsr .track/active PEK #02 MUL ADD #01 ADD PEK .Audio0/adsr .track/active PEK #10 MUL ADD #01 ADD DEI
DUP #f0 AND STH #01 .Mouse/state DEI #10 EQU #0e MUL ADD ADD #0f AND STHr ADD DUP #f0 AND STH #01 .Mouse/state DEI #10 EQU #0e MUL ADD ADD #0f AND STHr ADD
.adsr .track/active PEK #02 MUL ADD #01 ADD POK &no-r .Audio0/adsr .track/active PEK #10 MUL ADD #01 ADD DEO &no-r
DUP #05 NEQ ,&no-left JNZ DUP #05 NEQ ,&no-left JNZ
;volume #00 .track/active PEK ADD2 GET .Audio0/volume .track/active PEK #10 MUL ADD DEI
#10 .Mouse/state DEI #10 EQU #e0 MUL ADD ADD #10 .Mouse/state DEI #10 EQU #e0 MUL ADD ADD
;volume #00 .track/active PEK ADD2 PUT &no-left .Audio0/volume .track/active PEK #10 MUL ADD DEO &no-left
DUP #06 NEQ ,&no-right JNZ DUP #06 NEQ ,&no-right JNZ
;volume #00 .track/active PEK ADD2 GET .Audio0/volume .track/active PEK #10 MUL ADD DEI
DUP #f0 AND STH #01 .Mouse/state DEI #10 EQU #0e MUL ADD ADD #0f AND STHr ADD DUP #f0 AND STH #01 .Mouse/state DEI #10 EQU #0e MUL ADD ADD #0f AND STHr ADD
;volume #00 .track/active PEK ADD2 PUT &no-right .Audio0/volume .track/active PEK #10 MUL ADD DEO &no-right
POP POP
( release ) #00 .Mouse/state DEO ( release ) #00 .Mouse/state DEO
;draw-controls JSR2 ;draw-controls JSR2
@ -193,44 +196,28 @@ BRK
DUP #ff NEQ ,&skip1 JNZ DUP #ff NEQ ,&skip1 JNZ
POP ,&listen2 JMP POP ,&listen2 JMP
&skip1 &skip1
.adsr/ch1 PEK2 .Audio/adsr DEO2 #00 SWP ;notes ADD2 GET .Audio0/pitch DEO
.volume/ch1 PEK .Audio/volume DEO
;square-wave .Audio/addr DEO2
;square-wave/end ;square-wave SUB2 .Audio/len DEO2
#00 SWP ;notes ADD2 GET .Audio/pitch DEO
&listen2 &listen2
;track/ch2 #00 .head/pos PEK #08 DIV ADD2 GET ;track/ch2 #00 .head/pos PEK #08 DIV ADD2 GET
#01 SUB #01 SUB
DUP #ff NEQ ,&skip2 JNZ DUP #ff NEQ ,&skip2 JNZ
POP ,&listen3 JMP POP ,&listen3 JMP
&skip2 &skip2
.adsr/ch2 PEK2 .Audio/adsr DEO2 #00 SWP ;notes ADD2 GET .Audio1/pitch DEO
.volume/ch2 PEK .Audio/volume DEO
;triangle-wave .Audio/addr DEO2
;triangle-wave/end ;triangle-wave SUB2 .Audio/len DEO2
#00 SWP ;notes ADD2 GET .Audio/pitch DEO
&listen3 &listen3
;track/ch3 #00 .head/pos PEK #08 DIV ADD2 GET ;track/ch3 #00 .head/pos PEK #08 DIV ADD2 GET
#01 SUB #01 SUB
DUP #ff NEQ ,&skip3 JNZ DUP #ff NEQ ,&skip3 JNZ
POP ,&listen4 JMP POP ,&listen4 JMP
&skip3 &skip3
.adsr/ch3 PEK2 .Audio/adsr DEO2 #00 SWP ;notes ADD2 GET .Audio2/pitch DEO
.volume/ch3 PEK .Audio/volume DEO
;sine-wave .Audio/addr DEO2
;sine-wave/end ;sine-wave SUB2 .Audio/len DEO2
#00 SWP ;notes ADD2 GET .Audio/pitch DEO
&listen4 &listen4
;track/ch4 #00 .head/pos PEK #08 DIV ADD2 GET ;track/ch4 #00 .head/pos PEK #08 DIV ADD2 GET
#01 SUB #01 SUB
DUP #ff NEQ ,&skip4 JNZ DUP #ff NEQ ,&skip4 JNZ
POP ,&end JMP POP ,&end JMP
&skip4 &skip4
#0000 .Audio/adsr DEO2 #00 SWP ;notes ADD2 GET #80 ORA .Audio3/pitch DEO
.volume/ch4 PEK .Audio/volume DEO
;noise-wave .Audio/addr DEO2
;noise-wave-end ;noise-wave SUB2 .Audio/len DEO2
#00 SWP ;notes ADD2 GET #80 ORA .Audio/pitch DEO
&end &end
RTN RTN
@ -400,31 +387,31 @@ RTN
( env ) ( env )
.ctlframe/x1 PEK2 8+ .ctlframe/y1 PEK2 8+ #22 ;env_txt ;draw-label JSR2 .ctlframe/x1 PEK2 8+ .ctlframe/y1 PEK2 8+ #22 ;env_txt ;draw-label JSR2
.ctlframe/x1 PEK2 8+ .ctlframe/y1 PEK2 #0010 ADD2 .ctlframe/x1 PEK2 8+ .ctlframe/y1 PEK2 #0010 ADD2
.adsr .track/active PEK #02 MUL ADD PEK #04 SFT .Audio0/adsr .track/active PEK #10 MUL ADD DEI #04 SFT
;draw-knob JSR2 ;draw-knob JSR2
.ctlframe/x1 PEK2 #0018 ADD2 .ctlframe/y1 PEK2 #0010 ADD2 .ctlframe/x1 PEK2 #0018 ADD2 .ctlframe/y1 PEK2 #0010 ADD2
.adsr .track/active PEK #02 MUL ADD PEK #0f AND .Audio0/adsr .track/active PEK #10 MUL ADD DEI #0f AND
;draw-knob JSR2 ;draw-knob JSR2
.ctlframe/x1 PEK2 #0028 ADD2 .ctlframe/y1 PEK2 #0010 ADD2 .ctlframe/x1 PEK2 #0028 ADD2 .ctlframe/y1 PEK2 #0010 ADD2
.adsr .track/active PEK #02 MUL ADD #01 ADD PEK #04 SFT .Audio0/adsr .track/active PEK #10 MUL ADD #01 ADD DEI #04 SFT
;draw-knob JSR2 ;draw-knob JSR2
.ctlframe/x1 PEK2 #0038 ADD2 .ctlframe/y1 PEK2 #0010 ADD2 .ctlframe/x1 PEK2 #0038 ADD2 .ctlframe/y1 PEK2 #0010 ADD2
.adsr .track/active PEK #02 MUL ADD #01 ADD PEK #0f AND .Audio0/adsr .track/active PEK #10 MUL ADD #01 ADD DEI #0f AND
;draw-knob JSR2 ;draw-knob JSR2
( vol ) ( vol )
.ctlframe/x1 PEK2 #0058 ADD2 .ctlframe/y1 PEK2 8+ #22 ;vol_txt ;draw-label JSR2 .ctlframe/x1 PEK2 #0058 ADD2 .ctlframe/y1 PEK2 8+ #22 ;vol_txt ;draw-label JSR2
.ctlframe/x1 PEK2 #0058 ADD2 .ctlframe/y1 PEK2 #0010 ADD2 .ctlframe/x1 PEK2 #0058 ADD2 .ctlframe/y1 PEK2 #0010 ADD2
;volume #00 .track/active PEK ADD2 GET #04 SFT .Audio0/volume .track/active PEK #10 MUL ADD DEI #04 SFT
;draw-knob/force JSR2 ;draw-knob/force JSR2
.ctlframe/x1 PEK2 #0068 ADD2 .ctlframe/y1 PEK2 #0010 ADD2 .ctlframe/x1 PEK2 #0068 ADD2 .ctlframe/y1 PEK2 #0010 ADD2
;volume #00 .track/active PEK ADD2 GET #0f AND .Audio0/volume .track/active PEK #10 MUL ADD DEI #0f AND
;draw-knob/force JSR2 ;draw-knob/force JSR2
RTN RTN
@draw-vu ( -- ) @draw-vu ( -- )
.ctlframe/x1 PEK2 #0088 ADD2 .ctlframe/y1 PEK2 #0010 ADD2 .ctlframe/x1 PEK2 #0088 ADD2 .ctlframe/y1 PEK2 #0010 ADD2
.Audio/volume DEI DUP STH #04 SFT .Audio0/output .track/active PEK #10 MUL ADD DEI DUP STH #04 SFT
;draw-knob/force JSR2 ;draw-knob/force JSR2
.ctlframe/x1 PEK2 #0098 ADD2 .ctlframe/y1 PEK2 #0010 ADD2 .ctlframe/x1 PEK2 #0098 ADD2 .ctlframe/y1 PEK2 #0010 ADD2
STHr #0f AND STHr #0f AND
@ -513,8 +500,8 @@ RTN
RTN RTN
@ch1_txt [ "SQR 00 ] @ch1_txt [ "SQR 20 00 ]
@ch2_txt [ "TRI 00 ] @ch2_txt [ "TRI 20 00 ]
@ch3_txt [ "SINE 00 ] @ch3_txt [ "SINE 00 ]
@ch4_txt [ "DRUM 00 ] @ch4_txt [ "DRUM 00 ]
@env_txt [ "Envelope 00 ] @env_txt [ "Envelope 00 ]

View File

@ -12,7 +12,7 @@
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ] |00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|10 @Console [ &pad $8 &char $1 &byte $1 &short $2 &string $2 ] |10 @Console [ &pad $8 &char $1 &byte $1 &short $2 &string $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ] |20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ]
|30 @Audio [ &pad $8 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ] |30 @Audio [ &vector $2 &output $1 &pad $5 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|70 @Midi [ &vector $2 &message $2 ] |70 @Midi [ &vector $2 &message $2 ]
|80 @Controller [ &vector $2 &button $1 &key $1 ] |80 @Controller [ &vector $2 &button $1 &key $1 ]
|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &chord $1 ] |90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &chord $1 ]
@ -87,9 +87,8 @@ BRK
.wave-view/x1 PEK2 #0028 ADD2 .Screen/x DEO2 .wave-view/x1 PEK2 #0028 ADD2 .Screen/x DEO2
.wave-view/y1 PEK2 #0010 SUB2 .Screen/y DEO2 .wave-view/y1 PEK2 #0010 SUB2 .Screen/y DEO2
.Audio/volume DEI #04 SFT TOS #0008 MUL2 ;meter ADD2 .Screen/addr DEO2 .Audio/output DEI #04 SFT TOS #0008 MUL2 ;meter ADD2 .Screen/addr DEO2
#21 .Screen/color DEO #21 .Screen/color DEO
#88 .Audio/volume DEO
BRK BRK

View File

@ -54,8 +54,8 @@ apu_render(Apu *c, Sint16 *sample, Sint16 *end)
c->i %= c->len; c->i %= c->len;
} }
s = (Sint8)(c->addr[c->i]) * envelope(c, c->age++); s = (Sint8)(c->addr[c->i]) * envelope(c, c->age++);
*sample++ += s * c->volume_l / 0x180; *sample++ += s * c->volume[0] / 0x180;
*sample++ += s * c->volume_r / 0x180; *sample++ += s * c->volume[1] / 0x180;
} }
} }
@ -81,17 +81,13 @@ apu_start(Apu *c, Uint16 adsr, Uint8 pitch)
} }
Uint8 Uint8
apu_get_vu(Apu *c, Apu *end) apu_get_vu(Apu *c)
{ {
size_t i; size_t i;
Sint32 sum[2] = {0, 0}; Sint32 sum[2];
for(; c < end; ++c) { if(!c->advance || !c->period) return 0;
if(!c->advance) continue;
sum[0] += envelope(c, c->age) * c->volume_l;
sum[1] += envelope(c, c->age) * c->volume_r;
}
for(i = 0; i < 2; ++i) { for(i = 0; i < 2; ++i) {
sum[i] /= 0x800; sum[i] = envelope(c, c->age) * c->volume[i] / 0x800;
if(sum[i] > 0xf) sum[i] = 0xf; if(sum[i] > 0xf) sum[i] = 0xf;
} }
return (sum[0] << 4) | sum[1]; return (sum[0] << 4) | sum[1];

View File

@ -20,10 +20,10 @@ typedef struct {
Uint8 *addr; Uint8 *addr;
Uint32 count, advance, period, age, a, d, s, r; Uint32 count, advance, period, age, a, d, s, r;
Uint16 i, len; Uint16 i, len;
Sint8 volume_l, volume_r; Sint8 volume[2];
Uint8 pitch, repeat; Uint8 pitch, repeat;
} Apu; } Apu;
void apu_render(Apu *c, Sint16 *sample, Sint16 *end); void apu_render(Apu *c, Sint16 *sample, Sint16 *end);
void apu_start(Apu *c, Uint16 adsr, Uint8 pitch); void apu_start(Apu *c, Uint16 adsr, Uint8 pitch);
Uint8 apu_get_vu(Apu *c, Apu *end); Uint8 apu_get_vu(Apu *c);

View File

@ -25,7 +25,7 @@ static SDL_Texture *gTexture;
static Ppu ppu; static Ppu ppu;
static Apu apu[POLYPHONY]; static Apu apu[POLYPHONY];
static Mpu mpu; static Mpu mpu;
static Device *devscreen, *devmouse, *devctrl, *devmidi; static Device *devscreen, *devmouse, *devctrl, *devmidi, *devaudio0;
Uint8 zoom = 0, debug = 0, reqdraw = 0; Uint8 zoom = 0, debug = 0, reqdraw = 0;
@ -251,26 +251,21 @@ file_talk(Device *d, Uint8 b0, Uint8 w)
static void static void
audio_talk(Device *d, Uint8 b0, Uint8 w) audio_talk(Device *d, Uint8 b0, Uint8 w)
{ {
Apu *c; Apu *c = &apu[d - devaudio0];
if(!w) { if(!w && b0 == 0x2) {
if(b0 == 0xe) d->dat[0xe] = apu_get_vu(apu, apu + POLYPHONY); d->dat[0x2] = apu_get_vu(c);
return;
} }
c = &apu[d->dat[0x7] % POLYPHONY]; if(w && b0 == 0xf) {
SDL_LockAudioDevice(audio_id); SDL_LockAudioDevice(audio_id);
if(b0 == 0x1) c->period -= (Sint16)mempeek16(d->dat, 0x0); c->period -= (Sint16)mempeek16(d->dat, 0x0);
if(b0 == 0x3 || b0 == 0xf) c->len = mempeek16(d->dat, (b0 & 0x8) | 0x2); c->len = mempeek16(d->dat, 0xa);
if(b0 == 0x5 || b0 == 0xf) c->addr = &d->mem[mempeek16(d->dat, (b0 & 0x8) | 0x4)]; c->addr = &d->mem[mempeek16(d->dat, 0xc)];
if(b0 == 0x6 || b0 == 0xf) { c->volume[0] = d->dat[0xe] >> 4;
c->volume_l = d->dat[(b0 & 0x8) | 0x6] >> 4; c->volume[1] = d->dat[0xe] & 0xf;
c->volume_r = d->dat[(b0 & 0x8) | 0x6] & 0xf;
}
if(b0 == 0xf) {
c->repeat = !(d->dat[0xf] & 0x80); c->repeat = !(d->dat[0xf] & 0x80);
apu_start(c, mempeek16(d->dat, 0x8), d->dat[0xf] & 0x7f); apu_start(c, mempeek16(d->dat, 0x8), d->dat[0xf] & 0x7f);
d->dat[0x7]++; SDL_UnlockAudioDevice(audio_id);
} }
SDL_UnlockAudioDevice(audio_id);
} }
void void
@ -378,10 +373,10 @@ main(int argc, char **argv)
portuxn(&u, 0x0, "system", system_talk); portuxn(&u, 0x0, "system", system_talk);
portuxn(&u, 0x1, "console", console_talk); portuxn(&u, 0x1, "console", console_talk);
devscreen = portuxn(&u, 0x2, "screen", screen_talk); devscreen = portuxn(&u, 0x2, "screen", screen_talk);
portuxn(&u, 0x3, "audio", audio_talk); devaudio0 = portuxn(&u, 0x3, "audio0", audio_talk);
portuxn(&u, 0x4, "---", nil_talk); portuxn(&u, 0x4, "audio1", audio_talk);
portuxn(&u, 0x5, "---", nil_talk); portuxn(&u, 0x5, "audio2", audio_talk);
portuxn(&u, 0x6, "---", nil_talk); portuxn(&u, 0x6, "audio3", audio_talk);
devmidi = portuxn(&u, 0x7, "midi", midi_talk); devmidi = portuxn(&u, 0x7, "midi", midi_talk);
devctrl = portuxn(&u, 0x8, "controller", nil_talk); devctrl = portuxn(&u, 0x8, "controller", nil_talk);
devmouse = portuxn(&u, 0x9, "mouse", nil_talk); devmouse = portuxn(&u, 0x9, "mouse", nil_talk);