You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.8 KiB
133 lines
3.8 KiB
BITS 16 |
|
|
|
start: |
|
; Set up 4K stack after this bootloader |
|
; [Remember: Effective Address = Segment*16 + Offset] |
|
mov ax, 07C0h ; Set 'ax' equal to the location of this bootloader divided by 16 |
|
add ax, 20h ; Skip over the size of the bootloader divided by 16 |
|
mov ss, ax ; Set 'ss' to this location (the beginning of our stack region) |
|
mov sp, 4096 ; Set 'ss:sp' to the top of our 4K stack |
|
|
|
; Set data segment to where we're loaded so we can implicitly access all 64K from here |
|
mov ax, 07C0h ; Set 'ax' equal to the location of this bootloader divided by 16 |
|
mov ds, ax ; Set 'ds' to the this location |
|
|
|
; Print our message and stop execution |
|
mov si, message ; Put address of the null-terminated string to output into 'si' |
|
call print ; Call our string-printing routine |
|
|
|
mov ax, 0123h |
|
call printWordHex |
|
mov ax, 4567h |
|
call printWordHex |
|
mov ax, 89ABh |
|
call printWordHex |
|
call printCRLF |
|
mov ax, message |
|
call printWordHex |
|
|
|
|
|
;This goes first as to now overwrite %ah and %al. |
|
mov ax, 0h |
|
mov es, ax ;Section to write into |
|
mov ah, 02h ;Read sectors from drive |
|
mov al, 01h ;Number of sectors to read |
|
mov ch, 00h ;Low 8 bits of cylinder |
|
mov cl, 02h ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7) |
|
mov dh, 00h ;Head number |
|
mov dl, 00h ;Drive number |
|
mov bx, 0200h ;Offset into section |
|
int 13h ;Low level disk services |
|
; |
|
jnc notcarry |
|
mov si, error_str |
|
call print |
|
jmp endcarrycheck |
|
; |
|
notcarry: |
|
mov si, success_str |
|
call print |
|
jmp 0200h |
|
; |
|
endcarrycheck: |
|
cli ; Clear the Interrupt Flag (disable external interrupts) |
|
hlt ; Halt the CPU (until the next external interrupt) |
|
|
|
data: |
|
message db 'Boot SingOS!',13,10,0 |
|
error_str db 'Error', 0 |
|
success_str db 'Success', 0 |
|
|
|
; Routine for printing a 'ax' as hex |
|
printWordHex: |
|
mov bx, ax |
|
mov al, bh |
|
shr al, 4 |
|
add al, 48 |
|
mov ah, 0Eh |
|
int 10h |
|
mov al, bh |
|
and al, 0Fh |
|
add al, 48 |
|
int 10h |
|
mov al, bl |
|
shr al, 4 |
|
add al, 48 |
|
int 10h |
|
mov al, bl |
|
and al, 0Fh |
|
add al, 48 |
|
int 10h |
|
ret |
|
|
|
printCRLF: |
|
mov ah, 0Eh |
|
mov al, 13 |
|
int 10h |
|
mov al, 10 |
|
int 10h |
|
ret |
|
|
|
; Routine for outputting string in 'si' register to screen |
|
print: |
|
mov ah, 0Eh ; Specify 'int 10h' 'teletype output' function |
|
; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)] |
|
.printchar: |
|
lodsb ; Load byte at address SI into AL, and increment SI |
|
cmp al, 0 |
|
je .done ; If the character is zero (NUL), stop writing the string |
|
int 10h ; Otherwise, print the character via 'int 10h' |
|
jmp .printchar ; Repeat for the next character |
|
.done: |
|
ret |
|
|
|
|
|
; Pad to 510 bytes (boot sector size minus 2) with 0s, and finish with the two-byte standard boot signature |
|
times 510-($-$$) db 0 |
|
dw 0xAA55 ; => 0x55 0xAA (little endian byte order) |
|
|
|
;define_byte: |
|
; dw 1234h |
|
|
|
start_sing_os: |
|
mov si, welcome ; Put address of the null-terminated string to output into 'si' |
|
call print_os ; Call our string-printing routine |
|
cli |
|
hlt |
|
|
|
; Routine for outputting string in 'si' register to screen |
|
print_os: |
|
mov ah, 0Eh ; Specify 'int 10h' 'teletype output' function |
|
; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)] |
|
.printchar_os: |
|
lodsb ; Load byte at address SI into AL, and increment SI |
|
cmp al, 0 |
|
je .done_os ; If the character is zero (NUL), stop writing the string |
|
int 10h ; Otherwise, print the character via 'int 10h' |
|
jmp .printchar_os ; Repeat for the next character |
|
.done_os: |
|
ret |
|
|
|
data_os: |
|
welcome db 'This is SingOS!', 0 |
|
times 510 db 0 |