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