From: Eleni Maria Stea Date: Fri, 4 Dec 2020 15:53:38 +0000 (+0200) Subject: step 1: boot from floppy and clear screen X-Git-Url: https://eleni.mutantstargoat.com/git/?p=bootboot;a=commitdiff_plain;h=ed7544d82195f704b31bf78cb9ae1ca967b17a1f step 1: boot from floppy and clear screen --- ed7544d82195f704b31bf78cb9ae1ca967b17a1f diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e52a97e --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +bin = bootboot +# build flat binary (no headers) +ASFLAGS = -f bin +$(bin): bb.asm + nasm $(ASFLAGS) -o $@ $< + +floppy.img: $(bin) + dd if=/dev/zero of=$@ bs=1024 count=1440 + dd if=$< of=$@ bs=512 conv=notrunc + +.PHONY: clean +clean: + rm -f $(bin) + +# floppy disk A (fda) +.PHONY: run +run: floppy.img + qemu-system-i386 -fda $< diff --git a/bb.asm b/bb.asm new file mode 100644 index 0000000..f5c84af --- /dev/null +++ b/bb.asm @@ -0,0 +1,58 @@ +; org: all instructions from now on start in 7c00h +; 7c00h is where the bios loads the 1st sector +; assembler formatting: +; column 0: labels +; tab: commands + org 7c00h +; at boot: real mode (like it's 8086) +; we have to tell assembler that code is 16bit mode + bits 16 + +start: + mov sp, 7c00h + +; service 0: set videomode ah +; param: which video mode (13h: 320x200, 256 colors) al +; ax: ah (high 8 bits), al (low) + mov ax, 13h + +; calling video bios +; software interrupt 10h + int 10h + call clearscreen + +; infinite loop +end: + jmp end + +clearscreen: +; video ram is mapped in a0000 +; first 64000 bytes appear immediately on screen +; mem addresses in real mode have 2 parts: segment and offset +; bits overlap: segment is shifted by 4 and is added to the +; overlapping offset (20 bits number = x86's addressable space = 1MB) +; segment register for the segment: es, ds, cs, ss (and: fs, gs) +; default register = ds (data segment), es = extra segment +; cs = code segment cs:ip (it points where to read instructions and is +; automatically set to 7c0 (7c00h) +; offset can be paired with any register +; pair the registers + mov ax, 0a000h + mov ds, ax + mov di, 0 +; counter cx + mov cx, 64000 + mov ax, 3 +.loop_begin: +; dereferrence[] address + mov [di], al + inc di + dec cx +; when cx is 0, 0 flag is set + jnz .loop_begin + ret + +; assembler trick: write as many 0 needed to fill 510 bytes +; $ <- means here + times 510-($-$$) db 0 + dw 0aa55h