After using various registers settings borrowed from STANDARD.BNK included with adlib visual composer I decided on something which doesn't exactly sounds like lasers, but does a bit nicer.
Unfortunately I have now ran out of time and space so uploaded some binaries to this project page.
The scan1 or scan2 part in the filename indicates the scancode set used. Scan1 works in bochs, scan2 in qemu.
You can run one of the images using these emulators as follows:
The image are 64KB in size since that's the minimal size for a valid ROM image (or atleast to these emulators). The images with a demosong are oversized, but save you the hassle of actually using the tracker.
The images without demosong contain 1016 bytes of actual data, the zero initialized aren't used.
Turns out the keyboard code I wrote didn't really work as intended.
During christmas weekend I was using a different laptop to do some work on this project and I was quite surprised it would load fine in qemu, but the keyboard completely stopped working.
So I loaded it into bochs and this didn't work either, it loaded but no keyboard. I wasn't too surprised about bochs as I had done most testing in qemu so far.
So after diving into the cause I uncovered three problems:
- Bochs was using scancode set 1, qemu scancode set 2, I only implemented set 2
- I was not only reading the current scancode in the interrupt handler, but also the next scancodes for multibyte sequences. This worked fine in qemu, but bochs needs a delay for doing.
- The "christmas" laptop had a newer version of qemu. In this later version a kludge had been removed which used to support SeaBIOS. Apparently my code also relied on it.
The change in question is commit b8eb5512fd8a115f164edbbe897cdf8884920ccb, it removes initialization of the APIC, stopping it from delivering interrupts to the PIC.
- s->lvt[APIC_LVT_LINT0] = 0x700;
At first I figured just adding this code to my tracker would fix the problem. No such luck, the base address of the APIC registers is out of reach for real-mode code.
However there's another option, disabling the APIC using an MSR. I added code doing that, checked qemu code to see if it should work (hw/intc/apic.c, function apic_check_pic_intr) and figured it should work. No such luck however.
Reading up a bit on the APIC I discovered it's possible to adjust the APIC base address, making it reachable again:
mov $0x1b, %cx
# MSR for APIC
rdmsr
and $~(((1 << 24) - 1) << 12), %eax
# mask out base offset
or $(8 << 12), %eax
# remap physical base to 0x8000 aka %cs:0x7c00
wrmsr
mov $0x700, %eax
mov %eax, %cs:(0x7c00 + 0x350)
# set LINT0 to ExtINT mode
So filled with hope I fired up qemu up again, and still it didn't work.
So while the first two were easy to fix, getting interrupts again from the PIC in newer qemu didn't work out for me. In the end I rewrote the code to poll the keyboard and timer. This is a poor way of implementing it, since it's quite wasteful of CPU cycles. But it did turn out shorter in terms of bytes, I ditched all the PIC initialization code and didn't need to set interrupt handlers, some new bytes were introduced to divide the PIT counter.
Now atleast the code is under 1024 bytes again, it works in recent versions of both qemu and bochs.
If anyone can enlighten me on where I went wrong, I'd be happy to hear :)
Next step is polishing the sound. There notes are currently off-by-three, I'd like a demotrack and it should sound like lasers instead of like beeps.
Hi Michael, Just came across your 1kB entry, nice :)
I've been looking at entering using a standard PC too (we appear to be alone in this), but chose to write either a boot sector or BIOS extension ROM, since boot loaders are allowed, this may help with a few chipset issues you have?
BTW: I've not submitted anything yet, I stopped with a working loader and got distracted IRL!
Hi Michael, Just came across your 1kB entry, nice :)
I've been looking at entering using a standard PC too (we appear to be alone in this), but chose to write either a boot sector or BIOS extension ROM, since boot loaders are allowed, this may help with a few chipset issues you have?
BTW: I've not submitted anything yet, I stopped with a working loader and got distracted IRL!
https://github.com/phlash/hackaday-1k