# Draw pixels in response to keyboard events, starting from the top-left
# and in raster order.
#
# To run, first prepare a realistically sized disk image:
# dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB
# Load the program on the disk image:
# cat baremetal/boot.hex baremetal/ex3.hex |./bootstrap run apps/hex > a.bin
# dd if=a.bin of=disk.img conv=notrunc
# To run:
# qemu-system-i386 disk.img
# Or:
# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img
# main: (address 0x9000)
# eax <- LFB
8b # copy *rm32 to r32
05 # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32
28 7f 00 00 # disp32 [label]
# var read index/ecx: byte = 0
31 c9 # ecx <- xor ecx; 11/direct 001/r32/ecx 001/rm32/ecx
# $loop:
# CL = *read index
8a # copy m8 at r32 to r8
0d # 00/mod/indirect 001/r8/cl 101/rm32/use-disp32
cc 7d 00 00 # disp32 [label]
# CL = *(keyboard buffer + ecx)
8a # copy m8 at r32 to r8
89 # 10/mod/*+disp32 001/r8/cl 001/rm32/ecx
d0 7d 00 00 # disp32 [label]
# if (CL == 0) loop (spin loop)
80
f9 # 11/mod/direct 111/subop/compare 001/rm8/CL
00 # imm8
74 ef # loop -17 [label]
# offset 0x19:
# otherwise increment read index
fe # increment byte
05 # 00/mod/indirect 000/subop/increment 101/rm32/use-disp32
cc 7d 00 00 # disp32 [label]
# clear top nibble of index (keyboard buffer is circular)
80 # and byte
25 # 00/mod/indirect 100/subop/and 101/rm32/use-disp32
cc 7d 00 00 # disp32 [label]
0f # imm8
# print a pixel in fluorescent green
c6 # copy imm8 to m8 at rm32
00 # 00/mod/indirect 000/subop 000/rm32/eax
31 # imm32
40 # increment eax
eb dc # loop -36 [label]
# $break:
e9 fb ff ff ff # hang indefinitely
# vim:ft=subx