• Binaries

    michaelschrijver01/05/2017 at 23:15 0 comments

    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:

    $ qemu-system-x86_64 -bios image.bin -soundhw adlib
    $ bochs 'romimage: file=./image.bin'
    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.

    Memory Configuration
    Name             Origin             Length             Attributes
    *default*        0x0000000000000000 0xffffffffffffffff
    Linker script and memory map
    .text           0x0000000000000000      0x3e8
     .text          0x0000000000000000       0x4a bitdec.o
     .rodata        0x000000000000004a      0x39e bitdec.o
    .init           0x000000000000fff0       0x10
     .init          0x000000000000fff0       0x10 bitdec.o
    .data           0x0000000000010000        0x0
     .data          0x0000000000010000        0x0 bitdec.o
    .bss            0x0000000000004000        0x0
     .bss           0x0000000000004000        0x0 bitdec.o
    LOAD bitdec.o
    OUTPUT(bitdec.bin binary)

  • Progress

    michaelschrijver12/30/2016 at 19:51 0 comments

    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
        and     $~(((1 << 24) - 1) << 12), %eax    
        # mask out base offset
        or      $(8 << 12), %eax                   
        # remap physical base to 0x8000 aka %cs:0x7c00
        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.