uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

commit 7f5c4e25e45fdde0e9c3f7f0ec31ee0f5e6555ed
parent a206ed0b10f0a2afbfa5fb2d1a4cd2b439367237
Author: neauoire <aliceffekt@gmail.com>
Date:   Tue, 11 May 2021 11:42:12 -0700

Moved devices in their own folders

Diffstat:
Mbuild.sh | 24++++++++++++------------
Mprojects/demos/piano.usm | 91+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Dsrc/apu.c | 94-------------------------------------------------------------------------------
Asrc/devices/apu.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/apu.h -> src/devices/apu.h | 0
Rsrc/mpu.c -> src/devices/mpu.c | 0
Rsrc/mpu.h -> src/devices/mpu.h | 0
Rsrc/ppu.c -> src/devices/ppu.c | 0
Rsrc/ppu.h -> src/devices/ppu.h | 0
Msrc/emulator.c | 11+++++------
10 files changed, 158 insertions(+), 156 deletions(-)

diff --git a/build.sh b/build.sh @@ -3,18 +3,18 @@ echo "Formatting.." clang-format -i src/uxn.h clang-format -i src/uxn.c -clang-format -i src/ppu.h -clang-format -i src/ppu.c -clang-format -i src/apu.h -clang-format -i src/apu.c -clang-format -i src/mpu.h -clang-format -i src/mpu.c +clang-format -i src/devices/ppu.h +clang-format -i src/devices/ppu.c +clang-format -i src/devices/apu.h +clang-format -i src/devices/apu.c +clang-format -i src/devices/mpu.h +clang-format -i src/devices/mpu.c clang-format -i src/assembler.c clang-format -i src/emulator.c clang-format -i src/debugger.c echo "Cleaning.." -rm -f ./bin/assembler +rm -f ./bin/uxnasm rm -f ./bin/emulator rm -f ./bin/debugger rm -f ./bin/boot.rom @@ -24,17 +24,17 @@ mkdir -p bin if [ "${1}" = '--debug' ]; then echo "[debug]" - cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/assembler.c -o bin/assembler - cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/uxn.c src/ppu.c src/apu.c src/mpu.c src/emulator.c -L/usr/local/lib -lSDL2 -lportmidi -o bin/emulator + cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/assembler.c -o bin/uxnasm + cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/uxn.c src/devices/ppu.c src/devices/apu.c src/devices/mpu.c src/emulator.c -L/usr/local/lib -lSDL2 -lportmidi -o bin/emulator cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/uxn.c src/debugger.c -o bin/debugger else - cc src/assembler.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o bin/assembler + cc src/assembler.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o bin/uxnasm cc src/uxn.c src/debugger.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o bin/debugger - cc src/uxn.c src/ppu.c src/apu.c src/mpu.c src/emulator.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -lportmidi -o bin/emulator + cc src/uxn.c src/devices/ppu.c src/devices/apu.c src/devices/mpu.c src/emulator.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -lportmidi -o bin/emulator fi echo "Assembling.." -./bin/assembler projects/demos/piano.usm bin/boot.rom +./bin/uxnasm projects/demos/piano.usm bin/boot.rom echo "Running.." if [ "${2}" = '--cli' ]; diff --git a/projects/demos/piano.usm b/projects/demos/piano.usm @@ -47,10 +47,10 @@ #0f25 .System/b DEO2 ( vectors ) + ;on-frame .Screen/vector DEO2 ;on-control .Controller/vector DEO2 ;on-mouse .Mouse/vector DEO2 ;on-midi .Midi/vector DEO2 - ;on-frame .Screen/vector DEO2 ( load waveform ) ;piano-path .File/name DEO2 #0100 .File/length DEO2 WAVEFORM .File/load DEO2 @@ -113,6 +113,52 @@ BRK BRK +@on-control ( -> ) + + ( clear last cursor ) + #fff8 .Screen/addr DEO2 + .pointer/x LDZ2 .Screen/x DEO2 + .pointer/y LDZ2 .Screen/y DEO2 + #30 .Screen/color DEO + + .Controller/key DEI + DUP #61 ! ,&no-c JCN + #00 .last-note STZ ;notes LDA ;play JSR2 &no-c + DUP #73 ! ,&no-d JCN + #01 .last-note STZ ;notes #0001 ++ LDA ;play JSR2 &no-d + DUP #64 ! ,&no-e JCN + #02 .last-note STZ ;notes #0002 ++ LDA ;play JSR2 &no-e + DUP #66 ! ,&no-f JCN + #03 .last-note STZ ;notes #0003 ++ LDA ;play JSR2 &no-f + DUP #67 ! ,&no-g JCN + #04 .last-note STZ ;notes #0004 ++ LDA ;play JSR2 &no-g + DUP #68 ! ,&no-a JCN + #05 .last-note STZ ;notes #0005 ++ LDA ;play JSR2 &no-a + DUP #6a ! ,&no-b JCN + #06 .last-note STZ ;notes #0006 ++ LDA ;play JSR2 &no-b + DUP #6b ! ,&no-c2 JCN + #07 .last-note STZ ;notes #0007 ++ LDA ;play JSR2 &no-c2 + POP + + ( release ) + #00 .Controller/key DEO + + .Controller/button DEI #f0 AND + DUP #04 SFT #01 AND #01 ! ,&no-up JCN + ( move ) .Audio0/addr DEI2 #0001 -- .Audio0/addr DEO2 &no-up + DUP #05 SFT #01 AND #01 ! ,&no-down JCN + ( move ) .Audio0/addr DEI2 #0001 ++ .Audio0/addr DEO2 &no-down + DUP #06 SFT #01 AND #01 ! ,&no-left JCN + ( move ) .Audio0/addr DEI2 #0010 -- .Audio0/addr DEO2 &no-left + DUP #07 SFT #01 AND #01 ! ,&no-right JCN + ( move ) .Audio0/addr DEI2 #0010 ++ .Audio0/addr DEO2 &no-right + POP + + ;draw-octave JSR2 + ;draw-wave JSR2 + +BRK + @on-midi ( -> ) .Midi/note DEI #00 ! #01 JCN [ BRK ] @@ -204,49 +250,6 @@ BRK BRK -@on-control ( -> ) - - ( clear last cursor ) - #fff8 .Screen/addr DEO2 - .pointer/x LDZ2 .Screen/x DEO2 - .pointer/y LDZ2 .Screen/y DEO2 - #30 .Screen/color DEO - - .Controller/key DEI - DUP #61 ! ,&no-c JCN - #00 .last-note STZ ;notes LDA ;play JSR2 &no-c - DUP #73 ! ,&no-d JCN - #01 .last-note STZ ;notes #0001 ++ LDA ;play JSR2 &no-d - DUP #64 ! ,&no-e JCN - #02 .last-note STZ ;notes #0002 ++ LDA ;play JSR2 &no-e - DUP #66 ! ,&no-f JCN - #03 .last-note STZ ;notes #0003 ++ LDA ;play JSR2 &no-f - DUP #67 ! ,&no-g JCN - #04 .last-note STZ ;notes #0004 ++ LDA ;play JSR2 &no-g - DUP #68 ! ,&no-a JCN - #05 .last-note STZ ;notes #0005 ++ LDA ;play JSR2 &no-a - DUP #6a ! ,&no-b JCN - #06 .last-note STZ ;notes #0006 ++ LDA ;play JSR2 &no-b - DUP #6b ! ,&no-c2 JCN - #07 .last-note STZ ;notes #0007 ++ LDA ;play JSR2 &no-c2 - POP - - .Controller/button DEI #f0 AND - DUP #04 SFT #01 AND #01 ! ,&no-up JCN - ( move ) .Audio0/addr DEI2 #0001 -- .Audio0/addr DEO2 &no-up - DUP #05 SFT #01 AND #01 ! ,&no-down JCN - ( move ) .Audio0/addr DEI2 #0001 ++ .Audio0/addr DEO2 &no-down - DUP #06 SFT #01 AND #01 ! ,&no-left JCN - ( move ) .Audio0/addr DEI2 #0010 -- .Audio0/addr DEO2 &no-left - DUP #07 SFT #01 AND #01 ! ,&no-right JCN - ( move ) .Audio0/addr DEI2 #0010 ++ .Audio0/addr DEO2 &no-right - POP - - ;draw-octave JSR2 - ;draw-wave JSR2 - -BRK - @play ( pitch -- ) DUP .octave LDZ #0c * + .Audio0/pitch DEO diff --git a/src/apu.c b/src/apu.c @@ -1,94 +0,0 @@ -/* -Copyright (c) 2021 Devine Lu Linvega -Copyright (c) 2021 Andrew Alderwick - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE. -*/ - -#include "uxn.h" -#include "apu.h" - -#define NOTE_PERIOD 0x10000 -#define ADSR_STEP (SAMPLE_FREQUENCY / 0xf) - -/* clang-format off */ - -static Uint32 advances[12] = { - 0x80000, 0x879c8, 0x8facd, 0x9837f, 0xa1451, 0xaadc1, - 0xb504f, 0xbfc88, 0xcb2ff, 0xd7450, 0xe411f, 0xf1a1c -}; - -/* clang-format on */ - -static Sint32 -envelope(Apu *c, Uint32 age) -{ - if(!c->r) return 0x0888; - if(age < c->a) return 0x0888 * age / c->a; - if(age < c->d) return 0x0444 * (2 * c->d - c->a - age) / (c->d - c->a); - if(age < c->s) return 0x0444; - if(age < c->r) return 0x0444 * (c->r - age) / (c->r - c->s); - c->advance = 0; - return 0x0000; -} - -void -apu_render(Apu *c, Sint16 *sample, Sint16 *end) -{ - Sint32 s; - if(!c->advance || !c->period) return; - while(sample < end) { - c->count += c->advance; - c->i += c->count / c->period; - c->count %= c->period; - if(c->i >= c->len) { - if(!c->repeat) { - c->advance = 0; - return; - } - c->i %= c->len; - } - s = (Sint8)(c->addr[c->i] + 0x80) * envelope(c, c->age++); - *sample++ += s * c->volume[0] / 0x180; - *sample++ += s * c->volume[1] / 0x180; - } -} - -void -apu_start(Apu *c, Uint16 adsr, Uint8 pitch) -{ - if(pitch < 108 && c->len) - c->advance = advances[pitch % 12] >> (8 - pitch / 12); - else { - c->advance = 0; - return; - } - c->a = ADSR_STEP * (adsr >> 12); - c->d = ADSR_STEP * (adsr >> 8 & 0xf) + c->a; - c->s = ADSR_STEP * (adsr >> 4 & 0xf) + c->d; - c->r = ADSR_STEP * (adsr >> 0 & 0xf) + c->s; - c->age = 0; - c->i = 0; - if(c->len <= 0x100) /* single cycle mode */ - c->period = NOTE_PERIOD * 337 / 2 / c->len; - else /* sample repeat mode */ - c->period = NOTE_PERIOD; -} - -Uint8 -apu_get_vu(Apu *c) -{ - size_t i; - Sint32 sum[2]; - if(!c->advance || !c->period) return 0; - for(i = 0; i < 2; ++i) { - sum[i] = envelope(c, c->age) * c->volume[i] / 0x800; - if(sum[i] > 0xf) sum[i] = 0xf; - } - return (sum[0] << 4) | sum[1]; -} diff --git a/src/devices/apu.c b/src/devices/apu.c @@ -0,0 +1,94 @@ +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 Andrew Alderwick + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +#include "../uxn.h" +#include "apu.h" + +#define NOTE_PERIOD 0x10000 +#define ADSR_STEP (SAMPLE_FREQUENCY / 0xf) + +/* clang-format off */ + +static Uint32 advances[12] = { + 0x80000, 0x879c8, 0x8facd, 0x9837f, 0xa1451, 0xaadc1, + 0xb504f, 0xbfc88, 0xcb2ff, 0xd7450, 0xe411f, 0xf1a1c +}; + +/* clang-format on */ + +static Sint32 +envelope(Apu *c, Uint32 age) +{ + if(!c->r) return 0x0888; + if(age < c->a) return 0x0888 * age / c->a; + if(age < c->d) return 0x0444 * (2 * c->d - c->a - age) / (c->d - c->a); + if(age < c->s) return 0x0444; + if(age < c->r) return 0x0444 * (c->r - age) / (c->r - c->s); + c->advance = 0; + return 0x0000; +} + +void +apu_render(Apu *c, Sint16 *sample, Sint16 *end) +{ + Sint32 s; + if(!c->advance || !c->period) return; + while(sample < end) { + c->count += c->advance; + c->i += c->count / c->period; + c->count %= c->period; + if(c->i >= c->len) { + if(!c->repeat) { + c->advance = 0; + return; + } + c->i %= c->len; + } + s = (Sint8)(c->addr[c->i] + 0x80) * envelope(c, c->age++); + *sample++ += s * c->volume[0] / 0x180; + *sample++ += s * c->volume[1] / 0x180; + } +} + +void +apu_start(Apu *c, Uint16 adsr, Uint8 pitch) +{ + if(pitch < 108 && c->len) + c->advance = advances[pitch % 12] >> (8 - pitch / 12); + else { + c->advance = 0; + return; + } + c->a = ADSR_STEP * (adsr >> 12); + c->d = ADSR_STEP * (adsr >> 8 & 0xf) + c->a; + c->s = ADSR_STEP * (adsr >> 4 & 0xf) + c->d; + c->r = ADSR_STEP * (adsr >> 0 & 0xf) + c->s; + c->age = 0; + c->i = 0; + if(c->len <= 0x100) /* single cycle mode */ + c->period = NOTE_PERIOD * 337 / 2 / c->len; + else /* sample repeat mode */ + c->period = NOTE_PERIOD; +} + +Uint8 +apu_get_vu(Apu *c) +{ + size_t i; + Sint32 sum[2]; + if(!c->advance || !c->period) return 0; + for(i = 0; i < 2; ++i) { + sum[i] = envelope(c, c->age) * c->volume[i] / 0x800; + if(sum[i] > 0xf) sum[i] = 0xf; + } + return (sum[0] << 4) | sum[1]; +} diff --git a/src/apu.h b/src/devices/apu.h diff --git a/src/mpu.c b/src/devices/mpu.c diff --git a/src/mpu.h b/src/devices/mpu.h diff --git a/src/ppu.c b/src/devices/ppu.c diff --git a/src/ppu.h b/src/devices/ppu.h diff --git a/src/emulator.c b/src/emulator.c @@ -14,9 +14,9 @@ WITH REGARD TO THIS SOFTWARE. */ #include "uxn.h" -#include "ppu.h" -#include "apu.h" -#include "mpu.h" +#include "devices/ppu.h" +#include "devices/apu.h" +#include "devices/mpu.h" static SDL_AudioDeviceID audio_id; static SDL_Window *gWindow; @@ -328,11 +328,10 @@ start(Uxn *u) quit(); break; case SDL_TEXTINPUT: - if(event.text.text[0] >= ' ' || event.text.text[0] <= '~') - devctrl->dat[3] = event.text.text[0]; - break; case SDL_KEYDOWN: case SDL_KEYUP: + if(event.text.text[0] >= ' ' || event.text.text[0] <= '~') + devctrl->dat[3] = event.text.text[0]; doctrl(u, &event, event.type == SDL_KEYDOWN); evaluxn(u, mempeek16(devctrl->dat, 0)); devctrl->dat[3] = 0;