loadwarka/src/x86_stage1.S

145 lines
2.9 KiB
ArmAsm
Raw Normal View History

2022-01-26 21:52:30 +00:00
/*
Copyright (c) 2008-2009 Micah Elizabeth Scott
Copyright (c) 2022 Alex Kotov <kotovalexarian@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
2022-01-16 08:26:54 +00:00
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
2022-01-26 21:46:30 +00:00
2022-01-26 23:03:47 +00:00
#include "x86_common.h"
2022-01-26 21:46:30 +00:00
2022-01-26 20:19:39 +00:00
.code16
2022-01-16 08:26:54 +00:00
.global _start
.section .text
2022-01-26 23:16:14 +00:00
_start:
ljmp $0, $STAGE1_ADDR(main)
2022-01-27 00:21:22 +00:00
.align 4
size: .word _end - _start
2022-01-26 22:43:18 +00:00
disk: .byte 0
2022-01-27 00:21:22 +00:00
newline: .string "\r\n"
2022-01-26 23:16:14 +00:00
hello: .string "Hello stage 1!\r\n"
2022-01-27 00:28:39 +00:00
stage1_size_str: .string "Stage 1 size: "
stage2_size_str: .string "Stage 2 size: "
2022-01-26 21:33:27 +00:00
2022-01-26 23:03:47 +00:00
main:
cli
xor %ax, %ax
mov %ax, %ss
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
2022-01-26 23:03:47 +00:00
mov $STACK_BASE, %sp
2022-01-26 23:03:47 +00:00
mov %dl, STAGE1_ADDR(disk)
2022-01-26 21:33:27 +00:00
2022-01-27 00:21:22 +00:00
mov $STAGE1_ADDR(hello), %si
call print_str
2022-01-26 22:58:11 +00:00
mov $0x02, %ah
mov $1, %al /* Sectors count */
mov $0x80, %dl /* Drive */
mov $0, %ch /* Cylinder */
mov $0, %dh /* Head */
mov $2, %cl /* Cylinder and sector */
2022-01-26 23:03:47 +00:00
mov $STAGE2_BASE, %bx /* Address */
2022-01-26 20:19:39 +00:00
int $0x13
2022-01-27 00:28:39 +00:00
mov $STAGE1_ADDR(stage1_size_str), %si
call print_str
mov $STAGE1_ADDR(size), %bx
mov (%bx), %ax
call print_number
mov $STAGE1_ADDR(newline), %si
call print_str
mov $STAGE1_ADDR(stage2_size_str), %si
2022-01-27 00:21:22 +00:00
call print_str
mov $STAGE2_ADDR(size), %bx
mov (%bx), %ax
call print_number
mov $STAGE1_ADDR(newline), %si
2022-01-26 23:16:14 +00:00
call print_str
2022-01-26 23:03:47 +00:00
ljmp $0, $STAGE2_BASE
2022-01-26 20:19:39 +00:00
hang:
2022-01-26 20:19:39 +00:00
cli
hlt
jmp hang
2022-01-26 23:16:14 +00:00
do_ret:
ret
2022-01-27 00:26:54 +00:00
// AL - char
2022-01-26 23:16:14 +00:00
print_char:
2022-01-27 00:21:22 +00:00
mov $0x0e, %ah
2022-01-26 23:16:14 +00:00
mov $0x0001, %bx
int $0x10
jmp do_ret
2022-01-27 00:26:54 +00:00
// SI - string pointer
2022-01-26 23:16:14 +00:00
print_str:
lodsb
test %al, %al
jz do_ret
call print_char
jmp print_str
2022-01-27 00:21:22 +00:00
// AX - number
print_number:
test %ax, %ax
jnz print_number_notnull
mov $0x0e, %ah
mov $'0', %al
int $0x10
ret
// AX - number
print_number_notnull:
test %ax, %ax
jz do_ret
// DX - dividend high (always zero)
// AX - dividend low
xor %dx, %dx
// BX - divisor (always 10)
mov $10, %bx
// AX - quotient
// DX - remainder
div %bx
push %dx
call print_number_notnull
pop %dx
mov $0x0e, %ah
mov %dl, %al
add $'0', %al
int $0x10
ret
_end: