From fee07b6e1bdcfcc0cb289180e021acaec95d612b Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Fri, 25 Jul 2025 13:08:20 +0200 Subject: [PATCH] =?UTF-8?q?-=20[NEW]=20[ui]=20incoffset()=20i=20panel()=20?= =?UTF-8?q?-=20[NEW]=20m=C3=B2dul=20ay=5Fviewer=20-=20[NEW]=20[ay-3-8912]?= =?UTF-8?q?=20afegits=20m=C3=A8todes=20de=20debug=20-=20[FIX]=20[ay-3-8912?= =?UTF-8?q?]Arreglats=20uns=20quants=20tipus=20de=20dades=20-=20[FIX]=20[a?= =?UTF-8?q?y-3-8912]Arreglat=20el=20c=C3=A0lcul=20de=20la=20frequ=C3=A8nci?= =?UTF-8?q?a=20(en=20realitat=20amplitud)=20dels=20tonos=20-=20[FIX]=20[ay?= =?UTF-8?q?-3-8912]=20Arreglat=20el=20algoritme=20de=20c=C3=A0lcul=20del?= =?UTF-8?q?=20roido?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ay-3-8912.cpp | 95 ++++++++++++++++++++++++++++++++++----------------- ay-3-8912.h | 29 ++++++++++++++++ ay_viewer.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++ ay_viewer.h | 12 +++++++ main.cpp | 5 +++ ui.cpp | 17 +++++++++ ui.h | 2 ++ 7 files changed, 217 insertions(+), 31 deletions(-) create mode 100644 ay_viewer.cpp create mode 100644 ay_viewer.h diff --git a/ay-3-8912.cpp b/ay-3-8912.cpp index d4b8b7e..3f8c50c 100644 --- a/ay-3-8912.cpp +++ b/ay-3-8912.cpp @@ -29,26 +29,28 @@ namespace audio uint8_t selected_register {0}; uint8_t registers[16]; - uint16_t channel_a_tone_freq; - uint16_t channel_a_tone_freq_counter; - uint16_t channel_a_tone_level; - uint16_t channel_a_level; - uint16_t channel_b_tone_freq; - uint16_t channel_b_tone_freq_counter; - uint16_t channel_b_tone_level; - uint16_t channel_b_level; - uint16_t channel_c_tone_freq; - uint16_t channel_c_tone_freq_counter; - uint16_t channel_c_tone_level; - uint16_t channel_c_level; + uint32_t channel_a_tone_freq; + uint32_t channel_a_tone_freq_counter; + uint8_t channel_a_tone_level; + uint8_t channel_a_level; - uint8_t noise_freq; - uint8_t noise_freq_counter; + uint32_t channel_b_tone_freq; + uint32_t channel_b_tone_freq_counter; + uint8_t channel_b_tone_level; + uint8_t channel_b_level; + + uint32_t channel_c_tone_freq; + uint32_t channel_c_tone_freq_counter; + uint8_t channel_c_tone_level; + uint8_t channel_c_level; + + uint32_t noise_freq; + uint32_t noise_freq_counter; uint8_t noise_level; uint32_t shiftreg; - uint16_t envelope_freq; - uint16_t envelope_freq_counter; + uint32_t envelope_freq; + uint32_t envelope_freq_counter; int8_t envelope_volume; int8_t envelope_direction; @@ -65,40 +67,39 @@ namespace audio void write_register(int port, int val) { registers[selected_register] = val; - uint32_t clock = (z80::getClock() >> 4); switch (selected_register) { case 0: case 1: { - uint16_t freq = registers[0] | ((registers[1] & 0xf) << 8); - channel_a_tone_freq = clock / freq==0?1:freq; + uint32_t freq = uint32_t(registers[0]) + (uint32_t(registers[1]) * 256); + channel_a_tone_freq = (freq==0?1:freq)<<4; channel_a_tone_freq_counter = 0; break; } case 2: case 3: { - uint16_t freq = registers[2] | ((registers[3] & 0xf) << 8); - channel_b_tone_freq = clock / freq==0?1:freq; + uint32_t freq = uint32_t(registers[2]) + (uint32_t(registers[3]) * 256); + channel_b_tone_freq = (freq==0?1:freq)<<4; channel_b_tone_freq_counter = 0; break; } case 4: case 5: { - uint16_t freq = registers[4] | ((registers[5] & 0xf) << 8); - channel_c_tone_freq = clock / freq==0?1:freq; + uint32_t freq = uint32_t(registers[4]) + (uint32_t(registers[5]) * 256); + channel_c_tone_freq = (freq==0?1:freq)<<4; channel_c_tone_freq_counter = 0; break; } case 6: { - uint8_t freq = (registers[6] & 0x1f); - noise_freq = clock / freq==0?1:freq; + uint32_t freq = (registers[6] & 0x1f); + noise_freq = (freq==0?1:freq)<<4; noise_freq_counter = 0; break; } case 11: case 12: { - uint16_t freq = registers[11] | (registers[12] << 8); - envelope_freq = clock / freq==0?1:freq; + uint32_t freq = registers[11] | (registers[12] << 8); + envelope_freq = (freq==0?1:freq)<<4; break; } case 13: @@ -127,7 +128,7 @@ namespace audio void update(uint32_t dt) { - dt = dt >> 1; + //dt = dt >> 1; // Oscillate (0-1) channel A tone level given its frequency channel_a_tone_freq_counter+=dt; @@ -154,11 +155,14 @@ namespace audio noise_freq_counter+=dt; if (noise_freq_counter >= noise_freq) { noise_freq_counter -= noise_freq; - noise_level = noise_level ^ shiftreg; - uint32_t newbit = shiftreg ^ (shiftreg >> 3); - shiftreg = ((shiftreg >> 1) & 0xff) | ((newbit << 16) & 0x100); + //noise_level = noise_level ^ shiftreg; + //uint32_t newbit = shiftreg ^ (shiftreg >> 3); + //shiftreg = ((shiftreg >> 1) & 0xffff) | ((newbit << 16) & 0x10000); + shiftreg = (shiftreg * 2 + 1) ^ (((shiftreg >> 16) ^ (shiftreg >> 13)) & 1); + noise_level = ((shiftreg >> 16) & 1); } + // Develop (0-15) envelope volume given its frequency and shape envelope_freq_counter+=dt; if (envelope_freq_counter >= envelope_freq) { @@ -218,4 +222,33 @@ namespace audio return sample; } + namespace debug + { + uint8_t get_register(uint8_t num) { return registers[num]; } + uint32_t get_channel_a_tone_freq() { return channel_a_tone_freq; } + uint32_t get_channel_a_tone_freq_counter() { return channel_a_tone_freq_counter; } + uint8_t get_channel_a_tone_level() { return channel_a_tone_level; } + uint8_t get_channel_a_level() { return channel_a_level; } + + uint32_t get_channel_b_tone_freq() { return channel_b_tone_freq; } + uint32_t get_channel_b_tone_freq_counter() { return channel_b_tone_freq_counter; } + uint8_t get_channel_b_tone_level() { return channel_b_tone_level; } + uint8_t get_channel_b_level() { return channel_b_level; } + + uint32_t get_channel_c_tone_freq() { return channel_c_tone_freq; } + uint32_t get_channel_c_tone_freq_counter() { return channel_c_tone_freq_counter; } + uint8_t get_channel_c_tone_level() { return channel_c_tone_level; } + uint8_t get_channel_c_level() { return channel_c_level; } + + uint32_t get_noise_freq() { return noise_freq; } + uint32_t get_noise_freq_counter() { return noise_freq_counter; } + uint8_t get_noise_level() { return noise_level; } + uint32_t get_shiftreg() { return shiftreg; } + + uint32_t get_envelope_freq() { return envelope_freq; } + uint32_t get_envelope_freq_counter() { return envelope_freq_counter; } + int8_t get_envelope_volume() { return envelope_volume; } + int8_t get_envelope_direction() { return envelope_direction; } + } + } diff --git a/ay-3-8912.h b/ay-3-8912.h index 4a4e3da..6ea1731 100644 --- a/ay-3-8912.h +++ b/ay-3-8912.h @@ -13,4 +13,33 @@ namespace audio void update(uint32_t dt); uint8_t get_sample(); + + namespace debug + { + uint8_t get_register(uint8_t num); + uint32_t get_channel_a_tone_freq(); + uint32_t get_channel_a_tone_freq_counter(); + uint8_t get_channel_a_tone_level(); + uint8_t get_channel_a_level(); + + uint32_t get_channel_b_tone_freq(); + uint32_t get_channel_b_tone_freq_counter(); + uint8_t get_channel_b_tone_level(); + uint8_t get_channel_b_level(); + + uint32_t get_channel_c_tone_freq(); + uint32_t get_channel_c_tone_freq_counter(); + uint8_t get_channel_c_tone_level(); + uint8_t get_channel_c_level(); + + uint32_t get_noise_freq(); + uint32_t get_noise_freq_counter(); + uint8_t get_noise_level(); + uint32_t get_shiftreg(); + + uint32_t get_envelope_freq(); + uint32_t get_envelope_freq_counter(); + int8_t get_envelope_volume(); + int8_t get_envelope_direction(); + } } diff --git a/ay_viewer.cpp b/ay_viewer.cpp new file mode 100644 index 0000000..e5aceda --- /dev/null +++ b/ay_viewer.cpp @@ -0,0 +1,88 @@ +#include "ay_viewer.h" +#include "ui.h" +#include "ay-3-8912.h" + +void ay_viewer::show() +{ + if (!win) + { + win = SDL_CreateWindow("AY-3-8912 Viewer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_SHOWN); + ren = SDL_CreateRenderer(win, -1, 0); + tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 512, 512); + uitex = ui::createtexture(ren); + + //ui::window::registerWindow(SDL_GetWindowID(win), handleEvent); + } + refresh(); +} + +void ay_viewer::refresh() +{ + if (!win) return; + + ui::setrenderer(ren, uitex); + +/* + Uint32 *pixels; + int pitch; + SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch); + for (int i=0; i<65536; ++i) + { + //uint8_t tag = z80::getMemTag(i); + //pixels[i] = tag==MEMTAG_NONE ? 0x808080 : tag==MEMTAG_DATA ? 0x0000FF : tag==MEMTAG_MIXED ? 0xFF00FF : 0x00FF00; + uint32_t none_color = i<0x4000 ? 0x101010 : i<0x5800 ? 0x202020 : i<0x5b00 ? 0x404040 : 0x808080; + uint8_t tag = mem::getTag(i); + pixels[i] = !(tag & MEMTAG_TOUCHED) ? none_color : (tag & MEMTAG_TINST) ? 0x00FF00 : (tag & MEMTAG_TREPEAT) ? 0xFF0000 : 0x0000FF; + } + pixels[z80::getPC()] = 0xFFFFFF; + + SDL_UnlockTexture(tex); + SDL_RenderCopy(ren, tex, NULL, NULL); +*/ + SDL_SetRenderDrawColor(ren, 30, 30, 30, 255); + SDL_RenderClear(ren); + + char temp[256]; + + ui::panel(0,0,9,18,"REG:"); + + for (int i=0; i<16; ++i) { + sprintf(temp, "%2u: %3u", i, audio::debug::get_register(i)); + ui::printtxt(0,i,temp, COLOR_WHITE); + } + + ui::panel(9,0,18,18,"CHANNEL A:"); + sprintf(temp, "TONE FREQ: %4u", audio::debug::get_channel_a_tone_freq()); + ui::printtxt(0,0,temp, COLOR_WHITE); + sprintf(temp, "COUNTER: %4u", audio::debug::get_channel_a_tone_freq_counter()); + ui::printtxt(0,1,temp, COLOR_WHITE); + sprintf(temp, "TONE LEVL: %1u", audio::debug::get_channel_a_tone_level()); + ui::printtxt(0,2,temp, COLOR_WHITE); + sprintf(temp, "LEVEL: %1u", audio::debug::get_channel_a_level()); + ui::printtxt(0,3,temp, COLOR_WHITE); + + + SDL_RenderPresent(ren); +} + +void ay_viewer::hide() +{ + //ui::window::unregisterWindow(SDL_GetWindowID(win)); + SDL_DestroyTexture(uitex); uitex = nullptr; + SDL_DestroyTexture(tex); tex = nullptr; + SDL_DestroyRenderer(ren); ren = nullptr; + SDL_DestroyWindow(win); win = nullptr; +} + +void ay_viewer::focus() +{ + if (win) { + SDL_RaiseWindow(win); + refresh(); + } +} + +bool ay_viewer::handleEvent(SDL_Event *e) +{ + return true; +} diff --git a/ay_viewer.h b/ay_viewer.h new file mode 100644 index 0000000..1aefd82 --- /dev/null +++ b/ay_viewer.h @@ -0,0 +1,12 @@ +#pragma once +#include "z80viewer.h" + +class ay_viewer : public z80viewer +{ + public: + void show(); + void refresh(); + void hide(); + void focus(); + bool handleEvent(SDL_Event *e); +}; diff --git a/main.cpp b/main.cpp index 1c2b755..0ba403d 100644 --- a/main.cpp +++ b/main.cpp @@ -20,6 +20,7 @@ //#include "zx_128bankviewer.h" //#include "zx_128pageviewer.h" #include "ay-3-8912.h" +#include "ay_viewer.h" //uint8_t memory[65536]; uint32_t time = 0; @@ -98,6 +99,10 @@ int main(int argc, char *argv[]) //zxscreen::init(SCREEN_MODE_48K); zxscreen::init(SCREEN_MODE_128K); + //ay_viewer *v = new ay_viewer(); + //v->show(); + //z80viewer::registerViewer("AY", v); + //z80viewer *v = new zx_128bankviewer(); //v->show(); //z80viewer::registerViewer("128BANK", v); diff --git a/ui.cpp b/ui.cpp index 0618628..90d069b 100644 --- a/ui.cpp +++ b/ui.cpp @@ -51,6 +51,23 @@ namespace ui offset_y = y; } + void incoffset(uint8_t x, uint8_t y) + { + offset_x += x; + offset_y += y; + } + + void panel(int x, int y, int w, int h, const char *title) + { + ui::setoffset(x, y); + + ui::box(0,0,w,h,COLOR_WHITE); + ui::printrect(2,0, strlen(title)+2,1, COLOR_DARK); + ui::printtxt(3,0, title, COLOR_WHITE); + + ui::incoffset(1, 1); + } + void box(int x, int y, int w, int h, uint8_t color) { SDL_Rect rect {((offset_x+x)*CHR_W)+3, ((offset_y+y)*CHR_H)+6, w*CHR_W-6, h*CHR_H-13}; diff --git a/ui.h b/ui.h index 9df7ec5..2a0fb86 100644 --- a/ui.h +++ b/ui.h @@ -26,7 +26,9 @@ namespace ui SDL_Texture * createtexture(SDL_Renderer *renderer); void setrenderer(SDL_Renderer *renderer, SDL_Texture *texture); void setoffset(uint8_t x, uint8_t y); + void incoffset(uint8_t x, uint8_t y); + void panel(int x, int y, int w, int h, const char *title); void box(int x, int y, int w, int h, uint8_t color); void printrect(int x, int y, int w, int h, uint8_t color); void printvoidrect(int x, int y, int w, int h, uint8_t color);