In case you're wondering why I would bother with PC speaker sound when it's SO BAD, it's because I can't play soundblaster sounds without DMA and I can't do DMA without breaking my no assembly hacks rule
I might try using an OPL channel for sound effects but I don't know how that'll hold up for 30/35fps (since you can't buffer OPL commands) and also I don't know how much harder reserving one channel would make authoring music
@eniko there is a tracker software for pc speaker: Monotone. Not sure if that helps, but I found it pretty impressive, It has multi-voice and arpeggios 😍

@eniko Okay, that's what I meant when I asked the introductory question. Fair enough.
By the way, you really wouldn't want to use strings, at least not for resident asm functions. Strings can be relocated in garbage collection. I don't think arrays get relocated unless you resize them.
@eniko If it helps any, there is prescident for doing sound effects through the garbo pc speaker, tho I wonder how many cases these days even come with a PC speaker. Several of mine sure as shit haven't. o-o;
But yeah I grew up with PC speaker crap and I remember my dad putting a weird little utility into windows 3.11 that allowed the jank ass pc speaker to actually play .wav files out of it in windows. Like, actually play them. It was horrid of course, it all sounded like absolute garboleum and would only work for Windows, but it was pretty impressive regardless, turning somethign that was designed only to beep error codes and screech horrid sound at you into something that could play something RESEMBLIING actual sound.
Not sure what you are looking for?
I had a lot of fun with this tool ages ago.
@eniko I very very briefly looked into pc speaker music when I was trying to see how low bit you could go in the chiptune scene around 2011.
The tracker MONOTONE is written in pascal, which is a little fiddly, but it does pc speaker sounds in a slightly hardware-agnostic way.
https://github.com/MobyGamer/MONOTONE/tree/master
The source for the speaker output is here:
https://github.com/MobyGamer/MONOTONE/blob/master/MTSRC/MT_OUTP.PAS
I am not good at pascal, but my general understanding is that it reads the BIOS clock, waits for it to tick over once, then sends the note as a set frequency number to the memory address of the pc speaker. Then, on the next tick, it checks memory to see if it needs to send that same number to the speaker again or if it needs to set the speaker to a frequency that's impossible for it to make which results in it not making any noise at all.
@eniko It's more about how I went about managing the playback, but it turns out most of my PIT-related crimes that I was being coy about were also related to commanding the PC speaker, from background processing of normal tones (which I think would be QBASIC friendly) to 7-bit PWM digital playback (which would not).
I wrote it up at the time with sample code, so, spoilers ahoy:
https://bumbershootsoft.wordpress.com/2016/12/10/beyond-beep-boop-mastering-the-pc-speaker/
The PWM stuff is definitely one of the "weirdly clean for something accidental" things.
@moralrecordings i'm afraid of trying, so i don't know :'D
but testing in dosbox tells me i can get 57 notes per second out of the PLAY command which is enough for crude sound effects
speaking of 18.2Hz you wouldn't believe the day i had trying to lock framerate to 30/35 for slower machines
@moralrecordings well one thing i learned is that everyone is wrong about the raw channel0 PIT value when set to defaults. everywhere claims it goes 65535 to 0 then fires an irq when it underflows, and that's what sets the 18.2Hz clock
but it actually underflows *twice* per clock because it's a square wave and the irq only fires on the rising edge
Ah now I get it, you asked for “internal” speaker.
I remember it was straight forward in Turbo Pascal. Why are you restricted to basic?