1 ; org: all instructions from now on start in 7c00h
2 ; 7c00h is where the bios loads the 1st sector
3 ; assembler formatting:
7 ; at boot: real mode (like it's 8086)
8 ; we have to tell assembler that code is 16bit mode
14 ; initialize segment registers
21 ; bios sets in dl the num of the drive that
22 ; loaded you so if you overwrite dl you can reuse it
23 mov [saved_drive_num], dl
25 ; service 0: set videomode ah
26 ; param: which video mode (13h: 320x200, 256 colors) al
27 ; ax: ah (high 8 bits), al (low)
28 ; call 0 = set_videomode it expects the video mode in al
29 ; ah : 0, al: 13, ax:ahal
33 ; software interrupt 10h
34 ; what's the value of ah? al=video mode when ah=0
35 ; which set which video mode
40 ; load 2nd sector from boot device and jump to it
41 ; bios helpers, 13h = disk io
44 mov ah, 02h ; call 2: read sectors into memory
45 mov al, 1 ; number of sectors to read
46 mov ch, 0 ; low 8 bits of cylinder number
47 mov cl, 2 ; sector number that starts from 1
48 mov dh, 0 ; head number
49 mov dl, [saved_drive_num] ; 8bits
52 ; error check: if carry flag isn't set jump to loaded code
59 ; video ram is mapped in a0000
60 ; first 64000 bytes appear immediately on screen
61 ; mem addresses in real mode have 2 parts: segment and offset
62 ; bits overlap: segment is shifted by 4 and is added to the
63 ; overlapping offset (20 bits number = x86's addressable space = 1MB)
64 ; segment register for the segment: es, ds, cs, ss (and: fs, gs)
65 ; default register = ds (data segment), es = extra segment
66 ; cs = code segment cs:ip (it points where to read instructions and is
67 ; automatically set to 7c0 (7c00h)
68 ; offset can be paired with any register
79 ; dereferrence[] address
83 ; when cx is 0, 0 flag is set
90 ; assembler trick: write as many 0 needed to fill 510 bytes
97 mov ax, 0a000h ; video segment points to video memory
99 mov bx, 0 ; video offset
105 test ax, 0ff00h ; lower 8 bits 0, highest 1, Z flag is set while < 256, test = and but doesnt change ax
109 mov [bx], al ; pixel written on screen
118 ; setup grayscale palette (64 first colors because ramdac uses 6 bits / color so 2^6)
119 ; ram dac (digital to analog converter) tis vga
120 ; in a ^ register which index we want to write
121 ; 3 writes in another ramdac register (data)
122 ; ramdac feature: when you need to set a palette
123 mov al, 0 ; first index
124 mov dx, 3c8h ; ramdac index registe
125 out dx, al ; because io port (address) > 255
126 inc dx ; ramdac data register: 3c9h
132 test al, 3fh ; test with 3fh to keep the lowest 6 bits of al
135 ; disable all interrupts (for bios to not read the keyboard)
141 xor bx, bx ; mov bx, 0 to clear the register
144 and ax, 3fh ; last six bits of eax (see rand)
147 cmp bx, 64000 ; num pixels
150 in al, 64h ; 60h = keyb data port, 64h = keyb status port
151 and al, 1 ; 1 = OUTBUF_FULL = the keyb controller out buf is full
152 jz main_loop ; no key pressed, loop back
153 in al, 60h ; reads the keyb that was pressed to reset the flag
155 ; re-enable all interrupts
161 ; random number generator
172 randmul dd 1103515245