[bits 16]
|
|
[org 0x0600]
|
|
%define STAGE1_BASE 0x7c00
|
|
%define STAGE2_BASE 0x0600
|
|
|
|
%define STACK_POINTER_MAX 0x2000
|
|
|
|
%macro HALT 0
|
|
%%h:
|
|
cli
|
|
hlt
|
|
jmp %%h
|
|
%endmacro
|
|
|
|
%macro CRLF 0
|
|
push ax
|
|
mov ax, 0xe00|13
|
|
int 0x10
|
|
mov al, 10
|
|
int 0x10
|
|
pop ax
|
|
%endmacro
|
|
|
|
segment Stage1 vstart=STAGE1_BASE
|
|
Stage1:
|
|
; Setup segments
|
|
cli
|
|
xor ax, ax
|
|
xor bx, bx
|
|
xor cx, cx
|
|
xor dx, dx
|
|
xor si, si
|
|
xor di, di
|
|
times 32-($-$$) nop
|
|
times 7 inc ax
|
|
times 40 nop
|
|
call PrintAxHex
|
|
call PrintCRLF
|
|
|
|
HALT
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
PrintAx:
|
|
PrintAxHex:
|
|
; Prints the contens of ax as a hexadecimal number
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
pusha ; save registers
|
|
mov dx, ax
|
|
mov ah, 0xE ; Teletype output
|
|
|
|
mov cx, 4 ; 4 nibbles in a 16 bit word
|
|
.PrintLoop:
|
|
rol dx, 4 ; rotate to next nibble
|
|
mov al, dl ; we copy to al because we need to mask only the low 4 bits
|
|
and al, 0xF ; Do the masking
|
|
add al, '0' ; convert to ASCII
|
|
|
|
; If we are greater than 9 ascii...
|
|
cmp al, '9'
|
|
jbe .SkipDiffToAsciiA
|
|
add al, 'A'-('9'+1) ; ...add 7 to make digits 10 to 15 be represented as 'A' to 'F'
|
|
.SkipDiffToAsciiA:
|
|
|
|
int 0x10 ; BIOS call 'output'
|
|
loop .PrintLoop
|
|
|
|
popa ; restore registers
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
PrintAxDec:
|
|
; Prints the contens of ax as a decimal number
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
pusha
|
|
|
|
mov bx, 10 ; Divisor
|
|
|
|
xor cx, cx ; Digit count starts at 0
|
|
|
|
.LoopDivide: ; finds digits and pushes them to stack
|
|
test ax, ax
|
|
jz .BreakLoopDivide
|
|
xor dx, dx
|
|
div bx ; dx = (dx:ax)%bx, ax = (dx:ax)/bx
|
|
push dx
|
|
inc cx ; Increase digit count
|
|
jmp .LoopDivide
|
|
.BreakLoopDivide:
|
|
|
|
.LoopPrint:
|
|
pop ax
|
|
add al, '0' ; Convert to ascii
|
|
mov ah, 0xE
|
|
int 0x10
|
|
loop .LoopPrint
|
|
|
|
popa
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
PrintCRLF:
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
pusha
|
|
mov ah, 0xE
|
|
mov al, 13
|
|
int 0x10
|
|
mov al, 10
|
|
int 0x10
|
|
popa
|
|
ret
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
times 510-($-$$) db 0 ; Zero-pad to boot signature
|
|
db 0x55, 0xAA ; Boot signature
|