Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/refactor32'

pull/4/head
Jakob Kjær-Kammersgaard pirms 5 gadiem
vecāks
revīzija
823955c556
6 mainītis faili ar 508 papildinājumiem un 286 dzēšanām
  1. +74
    -0
      IntToString.nasm
  2. +160
    -0
      Strings32.nasm
  3. +1
    -1
      bootloader.nasm
  4. Binārs
      demo
  5. +269
    -285
      go32bit.nasm
  6. +4
    -0
      kernel.nasm

+ 74
- 0
IntToString.nasm Parādīt failu

@ -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

+ 160
- 0
Strings32.nasm Parādīt failu

@ -0,0 +1,160 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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
; IN: al = padding char
; ASSUMES: that the justification width > string length
; ASSUMES: that the size of the string buffer > justification width
RightJustifyString:
pushad
pushfd
lea edi, [esi + edx-1]
lea esi, [esi + ecx-1]
sub edx, ecx
std ; Move string from the end
rep movsb ; |
mov ecx, edx
rep stosb ; Pad with AL
popfd
popad
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Copies ecx bytes
; IN: esi = source
; IN: edi = destination
; IN: ecx = number of bytes to copy
CopyData:
pushad
mov edx, ecx
and edx, 11b
shr ecx, 2
; ecx = quotient, edx = remainder
rep movsd
mov ecx, edx
rep movsb
popad
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 Parādīt failu

@ -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ārs
demo Parādīt failu


+ 269
- 285
go32bit.nasm Parādīt failu

@ -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,250 @@ 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, (100 << 20) - 1 ; 100M Addressable
mov ebp, esp
; Space for dynamic variables
sub esp, 200*4 ; 200 32-bit integers
push ebp
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
xor ecx, ecx
inc edx
cmp edx, 25-1
jne .DrawLoop
inc ecx
cmp ecx, VIDEO_X_RES
jne .DrawLoop
xor ecx, ecx
inc edx
cmp edx, VIDEO_Y_RES-2
jne .DrawLoop
pop ebp
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
mov eax, dword [Py]
sar eax, 4
call IntToString
add edi, 12*2
mov eax, [Zoom]
sar eax, 9
call IntToString
add [ColorOffset], dword 1
jmp DrawStuff
HALT:
cli
hlt
jmp HALT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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, [VarLabels]
lea edi, [ConversionBuffer]
mov ecx, VarLabelsLength
call CopyData
mov ebx, 10 ; Divisor
lea esi, [ConversionBuffer]
lea edi, [VIDEO + ScreenCoord(0, 24)]
mov ah, 0x0f
call PrintString
xor ecx, ecx ; Digit count starts at 0
mov [.sign], byte ' '
; lea esi, [ConversionBuffer]
mov eax, dword [Px]
sar eax, 4
call IntToString
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:
; lea esi, [ConversionBuffer]
; ecx set by IntToString
mov edx, 7
mov al, ' '
call RightJustifyString
; esi still ConversionBuffer
mov ecx, edx
lea edi, [VIDEO + ScreenCoord(StrXStart, 24)]
mov ah, 0x70
call PrintString
; lea esi, [ConversionBuffer]
mov eax, dword [Py]
sar eax, 4
call IntToString
add edi, 20
; lea esi, [ConversionBuffer]
; ecx set by IntToString
mov edx, 7
mov al, ' '
call RightJustifyString
test ecx, ecx
jnz .NotZero
; esi still ConversionBuffer
mov ecx, edx
lea edi, [VIDEO + ScreenCoord(StrYStart, 24)]
mov ah, 0x70
call PrintString
mov ax, (0x0f << 8) | '0'
stosw
popad
ret
.NotZero:
sub edi, ecx
sub edi, ecx
add [ColorOffset], dword 1
mov ah, 0x0f
mov al, byte [.sign]
stosw
jmp DrawStuff
.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
VarLabels: db "X:"
StrXStart equ $-VarLabels
db " "
db "Y:"
StrYStart equ $-VarLabels
db " "
VarLabelsLength equ $-VarLabels
ProtectedWelcomeStr: db " Placeholder for SingOS - 32 bit edition! ", 0
ProtectedWelcomeStrLength equ $-ProtectedWelcomeStr
TestStr: db "hello, world"
TestStrLength equ $-TestStr
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 Parādīt failu

@ -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

Notiek ielāde…
Atcelt
Saglabāt