Browse Source

Partial refactor

refactor32
Jakob Kjær-Kammersgaard 5 years ago
parent
commit
7fc691b6ad
7 changed files with 474 additions and 282 deletions
  1. +74
    -0
      IntToString.nasm
  2. BIN
      IntToString.o
  3. +149
    -0
      Strings32.nasm
  4. +1
    -1
      bootloader.nasm
  5. BIN
      demo
  6. +246
    -281
      go32bit.nasm
  7. +4
    -0
      kernel.nasm

+ 74
- 0
IntToString.nasm View File

@ -0,0 +1,74 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Puts the stringified version of eax on the stack
; IN: eax = number to write
; IN: edi = base of where to write string
; OUT: ecx = number of characters written to buffer
IntToString: ; (eax = number, edi = buffer base) -> ecx = number of characters
push eax
push edi
;push ecx
push edx
push esi
push ebp
mov ecx, edi ; store negative original buffer base
neg ecx ; (used for counting amount of characters)
test eax, eax
jns .not_negative
mov BYTE [edi], '-'
neg eax
add edi, 1
.not_negative:
mov esi, edi ; store pointer after potential negative sign character
mov ebp, 0xcccccccd ; ebp = 32 bit multiplicative reciprocal of 10
.divide_loop:
mov ebx, eax ; save number in ebx
mul ebp
shr edx, 3 ; edx = quotient
lea eax, [edx + edx*4] ; eax = quotient * 10 = (number - remainder)
add eax, eax ; |
sub ebx, eax ; ebx = number - (number - remainder) = remainder
add ebx, '0' ; remainder is our digit, turn it ASCII
mov BYTE [edi], bl ; store ASCII digit to buffer
lea edi, [edi+1]
mov eax, edx ; We need quotient in eax for 'mul'
test eax, eax
jne .divide_loop
add ecx, edi ; Update amount of characters
mov byte [edi], 0 ; Null terminator
lea edi, [edi-1] ; We incremented the buffer pointer once too much
.swap_loop:
cmp esi, edi
jae .done_swapping
movzx eax, BYTE [edi]
movzx edx, BYTE [esi]
mov BYTE [edi], dl
mov BYTE [esi], al
sub edi, 1
add esi, 1
jmp .swap_loop
.done_swapping:
pop ebp
pop esi
pop edx
;pop ecx
pop edi
pop eax
ret

BIN
IntToString.o View File


+ 149
- 0
Strings32.nasm View File

@ -0,0 +1,149 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Converts integer to string
; IN: eax = number to convert
; IN: edi = base of string buffer
; OUT: ecx = number of characters written to buffer
IntToString:
push eax
push esi
push edx
push edi
push ebp
mov ecx, esi ; store negative original buffer base
neg ecx ; (used for counting amount of characters)
test eax, eax
jns .not_negative
mov BYTE [esi], '-'
neg eax
add esi, 1
.not_negative:
mov edi, esi ; store pointer after potential negative sign character
mov ebp, 0xcccccccd ; ebp = 32 bit multiplicative reciprocal of 10
.divide_loop:
mov ebx, eax ; save number in ebx
mul ebp
shr edx, 3 ; edx = quotient
lea eax, [edx + edx*4] ; eax = quotient * 10 = (number - remainder)
add eax, eax ; |
sub ebx, eax ; ebx = number - (number - remainder) = remainder
add ebx, '0' ; remainder is our digit, turn it ASCII
mov BYTE [esi], bl ; store ASCII digit to buffer
lea esi, [esi+1]
mov eax, edx ; We need quotient in eax for 'mul'
test eax, eax
jne .divide_loop
add ecx, esi ; Update amount of characters
mov byte [esi], 0x00 ; Add null terminator to end of string
lea esi, [esi-1] ; We incremented the buffer pointer once too much
.swap_loop:
cmp edi, esi
jae .done_swapping
movzx eax, BYTE [esi]
movzx edx, BYTE [edi]
mov BYTE [esi], dl
mov BYTE [edi], al
sub esi, 1
add edi, 1
jmp .swap_loop
.done_swapping:
pop ebp
pop edi
pop edx
pop esi
pop eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Right justifies source string within the given justification width
; IN: esi = base of string buffer
; IN: edx = justification width
; IN: ecx = string length
; ASSUMES: that the justification width > string length
; ASSUMES: that the size of the string buffer > justification width
RightJustifyString:
push esi
push edx
push ecx
push eax
pushfd
lea esi, [esi + ecx] ; should include null terminator
lea edi, [esi + edx]
std
sub edx, ecx ; edx should be difference
.copy_loop:
lodsb ; al = char
stosb
sub ecx, 1
jnz .copy_loop
; mov al, byte ' '
; .pad_loop:
; movsb
; sub edx, 1
; jnz .pad_loop
pushfd
pop eax
pop ecx
pop edx
pop esi
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Puts the stringified version of eax on the stack
; IN: esi = base of string
; IN: ecx = string length
; IN: ah = character attributes
PrintString:
push ecx
push eax
push edi
push esi
.print_loop:
mov al, byte [esi]
mov word [edi], ax
lea esi, [esi+1]
lea edi, [edi+2]
sub ecx, 1
jnz .print_loop
pop esi
pop edi
pop eax
pop ecx
ret

+ 1
- 1
bootloader.nasm View File

@ -31,7 +31,7 @@ start:
mov si, enter_debug_mode
call print
call printCRLF
%IF 1
%IF 0
; here goes wait call, for the user to enter debug mode.
; Wating for 2 seconds:
mov ah, 0x86 ; code for waiting interupt call

BIN
demo View File


+ 246
- 281
go32bit.nasm View File

@ -12,6 +12,9 @@
%define GDT_DataSeg16Selector GDT_Selector(GDT_DataSeg16Index, 0, 0)
%define VIDEO 0xB8000
%define VIDEO_X_RES 80
%define VIDEO_Y_RES 25
%define ScreenCoord(x, y) (2*(VIDEO_X_RES*(y)+(x)))
; GDT Stuff
%define Data 0000b
@ -25,10 +28,10 @@
%macro GDT_NULL_ENTRY 1 ; address
%assign address %1
lea di, [address]
xor ax, ax
mov cx, 4
rep stosw
lea di, [address]
xor ax, ax
mov cx, 4
rep stosw
%assign GDT_COUNT (GDT_COUNT+1)
%endmacro
@ -55,10 +58,10 @@
%assign base_16_23 ((base >> 16) & 0xff)
%assign base_24_31 ((base >> 24) & 0xff)
mov WORD [es:(address + 0)], limit_0_15
mov WORD [es:(address + 2)], base_0_15
mov WORD [es:(address + 4)], base_16_23 | (access << 8)
mov WORD [es:(address + 6)], limit_16_19 | (flags << 4) | (base_24_31 << 8)
mov WORD [es:(address + 0)], limit_0_15
mov WORD [es:(address + 2)], base_0_15
mov WORD [es:(address + 4)], base_16_23 | (access << 8)
mov WORD [es:(address + 6)], limit_16_19 | (flags << 4) | (base_24_31 << 8)
%assign GDT_COUNT (GDT_COUNT+1)
%endmacro
@ -75,81 +78,81 @@ Enable_A20:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pushad ;Preserve registers
pushfd ;Preserve EFLAGS because we might disable interrupts
mov ax,0x2402 ;INT 15h AX=2402h: Query A20 status
int 0x15 ;Check to see if A20 gate is enabled
jc A20_No_BIOS ;Error? Don't use BIOS to enable gate
test al,1 ;Test Bit 0 of AL
je A20_Enabled ;A20 gate already enabled
mov ax,0x2401 ;INT 15h AX=2401h: Enable A20 gate
int 0x15 ;Use BIOS to enable A20 gate
jc A20_No_BIOS ;Error? Don't use BIOS to enable gate
or ah,ah ;Test AH
jnz A20_No_BIOS ;Non-zero? A20 gate may not be enabled
mov ax,0x2402 ;INT 15h AX=2402h: Query A20 status
int 0x15 ;Check to see if A20 gate is enabled
jc A20_No_BIOS ;Error? Don't use BIOS to enable gate
test al,1 ;Test Bit 0 of AL
je A20_Enabled ;A20 gate already enabled
mov ax,0x2401 ;INT 15h AX=2401h: Enable A20 gate
int 0x15 ;Use BIOS to enable A20 gate
jc A20_No_BIOS ;Error? Don't use BIOS to enable gate
or ah,ah ;Test AH
jnz A20_No_BIOS ;Non-zero? A20 gate may not be enabled
A20_Enabled:
popfd ;Restore EFLAGS
popad ;Restore registers
ret ;Return
A20_No_BIOS:
mov ax,0x2403 ;INT 15h AX=2403h: Query A20 support
int 0x15 ;Call BIOS to find out how the A20 gate can be enabled
jc A20_KBD ;Error? Assume that keyboard controller is the only option
test bx,1 ;Bit 0:Keyboard controller supported
je A20_KBD ;BIOS indicates that keyboard controller is supported
test bx,2 ;Bit 1:Fast A20 supported
je FAST_A20 ;BIOS indicated that Fast A20 is supported
call Check_A20 ;Test A20 gate manually
jc A20_Enabled ;A20 gate already enabled
mov ax,0x2403 ;INT 15h AX=2403h: Query A20 support
int 0x15 ;Call BIOS to find out how the A20 gate can be enabled
jc A20_KBD ;Error? Assume that keyboard controller is the only option
test bx,1 ;Bit 0:Keyboard controller supported
je A20_KBD ;BIOS indicates that keyboard controller is supported
test bx,2 ;Bit 1:Fast A20 supported
je FAST_A20 ;BIOS indicated that Fast A20 is supported
call Check_A20 ;Test A20 gate manually
jc A20_Enabled ;A20 gate already enabled
A20_Fail:
call A20_OUT_Wait ;"Unable to enable A20 gate!"
call A20_OUT_Wait ;"Unable to enable A20 gate!"
cli ;Disable interrupts
hlt ;Halt machine
FAST_A20:
in al,0x92 ;Read System Control Port A
test al,2 ;Test Fast A20 bit
jnz A20_Fail ;Bit already set, failed to enable A20 gate
or al,2 ;Set Bit 1:Enable Fast A20
and al,0xFE ;Always clear Bit 0 so that machine does not reboot
out 0x92,al ;Write to port 92h
call Check_A20 ;Check A20 gate
jc A20_Enabled ;Success?
in al,0x92 ;Read System Control Port A
test al,2 ;Test Fast A20 bit
jnz A20_Fail ;Bit already set, failed to enable A20 gate
or al,2 ;Set Bit 1:Enable Fast A20
and al,0xFE ;Always clear Bit 0 so that machine does not reboot
out 0x92,al ;Write to port 92h
call Check_A20 ;Check A20 gate
jc A20_Enabled ;Success?
cli ;No? something must have gone wrong
hlt ;Clear interrupts and halt machine
A20_KBD:
cli ;Disable interrupts
mov cx,50 ;Number of attempts to enable gate
mov cx,50 ;Number of attempts to enable gate
Use_KBD:
call A20_OUT_Wait ;Wait for keyboard
mov al,0xAD ;Disable Keyboard
out 0x64,al ;Wait for Keyboard
mov al,0xD0 ;Read Controller Output Port
out 0x64,al
call A20_IN_Wait ;Wait for Keyboard
in al,0x60 ;Read Data Port
push ax ;Save
call A20_OUT_Wait ;Wait for Keyboard
mov al,0xD1 ;Write Controller Output Port
out 0x64,al
call A20_OUT_Wait ;Wait for Keyboard
pop ax ;Get port data back
or al,10b ;Bit 1: Enable A20 gate
out 0x60,al ;Write to data port
call A20_OUT_Wait ;Wait for Keyboard
mov al,0xAE ;Enable Keyboard
out 0x64,al
call A20_OUT_Wait ;Wait for Keyboard
call Check_A20 ;Verify that gate is enabled
jc A20_Enabled ;Yes? Return
loop Use_KBD ;No? Keep trying
jmp A20_Fail ;Could not enable gate after 50 tries
call A20_OUT_Wait ;Wait for keyboard
mov al,0xAD ;Disable Keyboard
out 0x64,al ;Wait for Keyboard
mov al,0xD0 ;Read Controller Output Port
out 0x64,al
call A20_IN_Wait ;Wait for Keyboard
in al,0x60 ;Read Data Port
push ax ;Save
call A20_OUT_Wait ;Wait for Keyboard
mov al,0xD1 ;Write Controller Output Port
out 0x64,al
call A20_OUT_Wait ;Wait for Keyboard
pop ax ;Get port data back
or al,10b ;Bit 1: Enable A20 gate
out 0x60,al ;Write to data port
call A20_OUT_Wait ;Wait for Keyboard
mov al,0xAE ;Enable Keyboard
out 0x64,al
call A20_OUT_Wait ;Wait for Keyboard
call Check_A20 ;Verify that gate is enabled
jc A20_Enabled ;Yes? Return
loop Use_KBD ;No? Keep trying
jmp A20_Fail ;Could not enable gate after 50 tries
A20_OUT_Wait:
in al,0x64 ;Read status register
test al,10b ;Is port ready?
jnz A20_OUT_Wait ;Nope, wait
in al,0x64 ;Read status register
test al,10b ;Is port ready?
jnz A20_OUT_Wait ;Nope, wait
ret ;Yep, continue
A20_IN_Wait:
in al,0x64 ;Read status register
test al,1b ;Is port ready?
jz A20_IN_Wait ;Nope, wait
in al,0x64 ;Read status register
test al,1b ;Is port ready?
jz A20_IN_Wait ;Nope, wait
ret ;Yep, continue
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -160,15 +163,15 @@ Check_A20:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pushad ;Preserve registers
push es
mov ax, 0xFFFF
mov es, ax ;Extra segment:FFFF
cmp WORD [es:0x7DFE + 16], 0xAAFF ;See if boot signature is wrapped at FFFF:7E0E (Meaning FFFF:7E0E = 0:7DFE)
push es
mov ax, 0xFFFF
mov es, ax ;Extra segment:FFFF
cmp WORD [es:0x7DFE + 16], 0xAAFF ;See if boot signature is wrapped at FFFF:7E0E (Meaning FFFF:7E0E = 0:7DFE)
stc ; Assume we didn't wrap, yes A20
jne .End
jne .End
clc ; We did wrap, no A20
.End:
pop es
pop es
popad
ret
@ -179,38 +182,38 @@ Check_A20:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Go32Bit:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call Enable_A20
call Enable_A20
; Set screen mode
mov ax, 0x0003 ; AH=0 (Change video mode), AL=13h (Mode) = 320x200 - 256 colors
mov bx, 0x0000
int 0x10 ; Video BIOS interrupt
mov ax, 0x0003 ; AH=0 (Change video mode), AL=13h (Mode) = 320x200 - 256 colors
mov bx, 0x0000
int 0x10 ; Video BIOS interrupt
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Global Descriptor Table ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax, GDT_Paragraph
mov es, ax
mov cx, 4096
lea si, [GO32_COPY_BEGIN]
xor di, di
rep movsb
mov ax, GDT_Paragraph
mov es, ax
mov cx, 4096
lea si, [GO32_COPY_BEGIN]
xor di, di
rep movsb
%assign GDT_COUNT 0
GDT_NULL_ENTRY 0
GDT_ENTRY (GDT_CodeSegIndex*8), 0x00000000, 0xffffffff, CodeRead, 0, 1
GDT_ENTRY (GDT_DataSegIndex*8), 0x00000000, 0xffffffff, DataMutable, 0, 1
GDT_ENTRY (GDT_CodeSeg16Index*8), 0x00000000, 0xffffffff, CodeRead, 0, 0
GDT_ENTRY (GDT_DataSeg16Index*8), 0x00000000, 0xffffffff, DataMutable, 0, 0
GDT_NULL_ENTRY 0
GDT_ENTRY (GDT_CodeSegIndex*8), 0x00000000, 0xffffffff, CodeRead, 0, 1
GDT_ENTRY (GDT_DataSegIndex*8), 0x00000000, 0xffffffff, DataMutable, 0, 1
GDT_ENTRY (GDT_CodeSeg16Index*8), 0x00000000, 0xffffffff, CodeRead, 0, 0
GDT_ENTRY (GDT_DataSeg16Index*8), 0x00000000, 0xffffffff, DataMutable, 0, 0
cli
lgdt [GDT_Record]
lgdt [GDT_Record]
mov eax, cr0
or al, 1 ; set PE (Protection Enable) bit in CR0 (Control Register 0)
mov cr0, eax
mov eax, cr0
or al, 1 ; set PE (Protection Enable) bit in CR0 (Control Register 0)
mov cr0, eax
jmp ClearPrefetchQueue
jmp ClearPrefetchQueue
nop
nop
ClearPrefetchQueue:
@ -218,14 +221,14 @@ ClearPrefetchQueue:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Manually assembled long jump ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
db 0x66 ; 32bit override
db 0xea ; Long jump
dd ProtectedModeBaby ; Absolute address
dw GDT_CodeSegSelector ; Descriptor Selector
db 0x66 ; 32bit override
db 0xea ; Long jump
dd ProtectedModeBaby ; Absolute address
dw GDT_CodeSegSelector ; Descriptor Selector
GDT_Record:
dw (GDT_COUNT*8) - 1 ; Size of GDT in bytes minus 1
dd 0x1000*16 ; Linear address of GDT
dw (GDT_COUNT*8) - 1 ; Size of GDT in bytes minus 1
dd 0x1000*16 ; Linear address of GDT
@ -240,269 +243,231 @@ GDT_SPACE: times (GDT_COUNT*8) db 0
ProtectedModeBaby:
; Update Other Segments
mov ax, GDT_DataSegSelector
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, GDT_DataSegSelector
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
; Setup stack
mov esp, 0x8000000
mov ebp, esp
mov esp, 0x8000000
mov ebp, esp
DrawStuff:
xor ecx, ecx
xor edx, edx
lea edi, [VIDEO]
xor ecx, ecx
xor edx, edx
lea edi, [VIDEO]
mov ebp, dword [Zoom]
sar ebp, 9
jnz .DrawLoop
mov ebp, dword [Zoom]
sar ebp, 9
jnz .DrawLoop
mov ebp, 0x7fffffff
mov ebp, 0x7fffffff
.DrawLoop:
mov eax, [Px]
shr eax, 4
add eax, ecx
imul eax, eax
mov eax, [Px]
shr eax, 4
add eax, ecx
imul eax, eax
mov ebx, eax
mov ebx, eax
mov eax, [Py]
shr eax, 4
add eax, edx
add eax, edx
imul eax, eax
mov eax, [Py]
shr eax, 4
add eax, edx
add eax, edx
imul eax, eax
add ebx, eax
add ebx, eax
mov eax, [ColorOffset]
push edx
xor edx, edx
idiv ebp
pop edx
mov eax, [ColorOffset]
push edx
xor edx, edx
idiv ebp
pop edx
xchg eax, ebx
xchg eax, ebx
add ax, bx
add ax, bx
mov al, ah
mov al, ah
stosw
inc ecx
cmp ecx, 80
jne .DrawLoop
inc ecx
cmp ecx, VIDEO_X_RES
jne .DrawLoop
xor ecx, ecx
inc edx
cmp edx, 25-1
jne .DrawLoop
xor ecx, ecx
inc edx
cmp edx, VIDEO_Y_RES-2
jne .DrawLoop
cld
xor eax, eax
xor eax, eax
in al, IOKeyData ; Get the scan code from the keyboard
in al, IOKeyData ; Get the scan code from the keyboard
test al, 0x80
jnz .ThereWasNothing
test al, 0x80
jnz .ThereWasNothing
cmp al, 75; left
je .KeyLeft
cmp al, 75; left
je .KeyLeft
cmp al, 72; up
je .KeyUp
cmp al, 72; up
je .KeyUp
cmp al, 80; right
je .KeyDown
cmp al, 80; right
je .KeyDown
cmp al, 77; down
je .KeyRight
cmp al, 77; down
je .KeyRight
cmp al, 51; <
je .KeyLess
cmp al, 51; <
je .KeyLess
cmp al, 52; >
je .KeyGreater
cmp al, 52; >
je .KeyGreater
cmp al, 1 ; Escape
je .KeyEscape
cmp al, 1 ; Escape
je .KeyEscape
.ThereWasNothing:
mov [Key], byte ' '
jmp .PrintKeyLegend
; lea esi, [ProtectedWelcomeStr]
mov [Key], byte ' '
jmp .PrintKeyLegend
; lea esi, [ProtectedWelcomeStr]
.KeyEscape:
call Reboot
jmp .PrintKeyLegend
call Reboot
jmp .PrintKeyLegend
.KeyLeft:
mov [Key], byte 'L'
add [Px], dword -1
jmp .PrintKeyLegend
mov [Key], byte 'L'
add [Px], dword -1
jmp .PrintKeyLegend
.KeyUp:
mov [Key], byte 'U'
add [Py], dword -1
jmp .PrintKeyLegend
mov [Key], byte 'U'
add [Py], dword -1
jmp .PrintKeyLegend
.KeyRight:
mov [Key], byte 'R'
add [Px], dword 1
jmp .PrintKeyLegend
mov [Key], byte 'R'
add [Px], dword 1
jmp .PrintKeyLegend
.KeyDown:
mov [Key], byte 'D'
add [Py], dword 1
jmp .PrintKeyLegend
mov [Key], byte 'D'
add [Py], dword 1
jmp .PrintKeyLegend
.KeyLess:
mov [Key], byte '<'
add [Zoom], dword -1
jmp .PrintKeyLegend
mov [Key], byte '<'
add [Zoom], dword -1
jmp .PrintKeyLegend
.KeyGreater:
mov [Key], byte '>'
add [Zoom], dword 1
mov [Key], byte '>'
add [Zoom], dword 1
.PrintKeyLegend:
lea esi, [ThereWasSomethingStr]
lea esi, [ThereWasSomethingStr]
lea edi, [VIDEO+(80*24 + (80-11))*2]
; lea edi, [VIDEO+(80*2)*12+30*2]
mov ah, 0x0f
lea edi, [VIDEO + ScreenCoord((80-11), 24)]
mov ah, 0x2f
.print_loop:
mov al, BYTE [esi]
test al, al
jz .break_print_loop
mov al, BYTE [esi]
test al, al
jz .break_print_loop
stosw
inc esi
jmp .print_loop
inc esi
jmp .print_loop
.break_print_loop:
lea edi, [VIDEO + (80*24 + 1)*2]
push edi
mov ecx, 34
xor eax, eax
rep stosd
pop edi
mov eax, dword [Px]
sar eax, 4
call IntToString
add edi, 12*2
lea edi, [VIDEO + ScreenCoord(1, 24)]
mov ecx, 34
mov eax, 0
rep stosd
lea esi, [ConversionBuffer]
mov eax, dword [Px]
sar eax, 4
call IntToString
mov eax, dword [Py]
sar eax, 4
call IntToString
push ecx
add edi, 12*2
mov eax, [Zoom]
sar eax, 9
call IntToString
lea esi, [ConversionBuffer]
mov edx, 6
call RightJustifyString
add [ColorOffset], dword 1
jmp DrawStuff
HALT:
cli
hlt
jmp HALT
lea edi, [VIDEO + ScreenCoord(1, 24)]
mov ah, 0x0f
call PrintString
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IntToString:
; Puts the stringified version of eax on the stack
; IN: eax = number to write
; IN: edi = base of where to write string
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pushad
lea esi, [ConversionBuffer]
pop eax
call IntToString
lea esi, [ConversionBuffer]
lea edi, [VIDEO + ScreenCoord(40, 24)]
mov ah, 0x0f
call PrintString
mov ebx, 10 ; Divisor
xor ecx, ecx ; Digit count starts at 0
mov [.sign], byte ' '
; add edi, 12*2
test eax, eax
jns .loop_divide
neg eax
mov [.sign], byte '-'
.loop_divide: ; finds digits and pushes them to stack
test eax, eax
jz .break_loop_divide
xor edx, edx
idiv ebx ; edx = (edx:eax)%ebx, eax = (edx:eax)/ebx
inc ecx ; Increase digit count
mov byte [.buffer + ecx], dl
jmp .loop_divide
.break_loop_divide:
add edi, 20
; mov eax, dword [Py]
; sar eax, 4
; call IntToString
test ecx, ecx
jnz .NotZero
; add edi, 12*2
; mov eax, [Zoom]
; sar eax, 9
; call IntToString
mov ax, (0x0f << 8) | '0'
stosw
popad
ret
add [ColorOffset], dword 1
.NotZero:
jmp DrawStuff
sub edi, ecx
sub edi, ecx
mov ah, 0x0f
mov al, byte [.sign]
stosw
.loop_print:
test ecx, ecx
jz .break_loop_print
mov al, byte [.buffer + ecx]
add al, '0' ; Convert to ascii
mov ah, 0x0f
stosw
dec ecx
jmp .loop_print
.break_loop_print:
popad
ret
.buffer times 40 db 0
.sign db ' '
%include "Strings32.nasm"
Halt:
cli
hlt
jmp Halt
; ------------------------------------------------------------------------------
Reboot:
in al, 0x64
test al, 0x2 ; Wait for an empty Input Buffer
jne Reboot
mov al, 0xFE
out 0x64, al ; Send the reboot call to the keyboard controller
jmp Reboot
in al, 0x64
test al, 0x2 ; Wait for an empty Input Buffer
jne Reboot
mov al, 0xFE
out 0x64, al ; Send the reboot call to the keyboard controller
jmp Reboot
;;;;;;;;;;;;;;;;;;;;;;;;
;; Strings
;;;;;;;;;;;;;;;;;;;;;;;;
ProtectedWelcomeStr: db " Placeholder for SingOS - 32 bit edition! ", 0
ThereWasSomethingStr: db " KEY = '"
Key: db " ' ", 0
Px: dd 0
Py: dd 0
ColorOffset: dd 0
Zoom: dd (4<<9)
align 512
ProtectedWelcomeStr: db " Placeholder for SingOS - 32 bit edition! ", 0
ThereWasSomethingStr: db " KEY = '"
Key: db " ' ", 0
Px: dd 0
Py: dd 0
ColorOffset: dd 0
Zoom: dd (4<<9)
ConversionBuffer: times 40 db 0
align 512

+ 4
- 0
kernel.nasm View File

@ -24,6 +24,10 @@ sing_loaded: ; SingOS is ready for the user:
mov bp, sp
sing_ready: ; SingOS is ready for the user:
%if 1
call Go32Bit
%endif
call os_clear_screen
mov si, welcome ; Put address of the null-terminated string to output into 'si'
call print ; Call our string-printing routine

Loading…
Cancel
Save