fangorn/sunshine-qemu
public
ref:main
/*
* Boot sector that draws a known test pattern, with no guest agent or OS.
*
* VGA mode 13h (320x200, 256 colors) with an explicit palette:
* top-left red, top-right green, bottom-left blue, bottom-right white.
* A 16x16 square in the center alternates between black and yellow on every BIOS timer tick
* (about 18 times a second), so QEMU keeps sending damage for it.
*
* Build: see build_guest.sh (GNU as + ld, no other tools).
*/
.code16
.globl _start
_start:
cli
xor %ax, %ax
mov %ax, %ds
mov %ax, %ss
mov $0x7c00, %sp
cld
sti
/* VGA mode 13h */
mov $0x0013, %ax
int $0x10
/* palette entries 1..6, 6-bit DAC values */
mov $0x3c8, %dx
mov $1, %al
outb %al, %dx
inc %dx
mov $palette, %si
mov $18, %cx
set_palette:
lodsb
outb %al, %dx
loop set_palette
/* quadrants: color = 1 + (x >= 160) + 2 * (y >= 100) */
mov $0xa000, %ax
mov %ax, %es
xor %di, %di
xor %bx, %bx
fill_row:
xor %cx, %cx
fill_col:
mov $1, %al
cmp $160, %cx
jb 1f
inc %al
1:
cmp $100, %bx
jb 2f
add $2, %al
2:
stosb
inc %cx
cmp $320, %cx
jb fill_col
inc %bx
cmp $200, %bx
jb fill_row
animate:
/* BIOS tick count in CX:DX; odd ticks draw yellow (6), even ticks black (5) */
xor %ah, %ah
int $0x1a
mov %dl, %al
and $1, %al
add $5, %al
mov $92, %bx
square_row:
/* di = y * 320 + 152 */
mov %bx, %di
shl $6, %di
mov %bx, %dx
shl $8, %dx
add %dx, %di
add $152, %di
mov $16, %cx
rep stosb
inc %bx
cmp $108, %bx
jb square_row
hlt
jmp animate
palette:
.byte 63, 0, 0 /* 1: red */
.byte 0, 63, 0 /* 2: green */
.byte 0, 0, 63 /* 3: blue */
.byte 63, 63, 63 /* 4: white */
.byte 0, 0, 0 /* 5: black */
.byte 63, 63, 0 /* 6: yellow */
.org 510
.word 0xaa55