From 7fc691b6ad635766a7f5a876869894fd6f693d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20Kj=C3=A6r-Kammersgaard?= Date: Wed, 21 Nov 2018 19:21:54 +0100 Subject: [PATCH] Partial refactor --- IntToString.nasm | 74 +++++++ IntToString.o | Bin 0 -> 992 bytes Strings32.nasm | 149 ++++++++++++++ bootloader.nasm | 2 +- demo | Bin 0 -> 488 bytes go32bit.nasm | 527 ++++++++++++++++++++++------------------------- kernel.nasm | 4 + 7 files changed, 474 insertions(+), 282 deletions(-) create mode 100644 IntToString.nasm create mode 100644 IntToString.o create mode 100644 Strings32.nasm create mode 100644 demo diff --git a/IntToString.nasm b/IntToString.nasm new file mode 100644 index 0000000..615e29c --- /dev/null +++ b/IntToString.nasm @@ -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 \ No newline at end of file diff --git a/IntToString.o b/IntToString.o new file mode 100644 index 0000000000000000000000000000000000000000..ff4c2b058c2f6e591501ed7805008e3bfee23a88 GIT binary patch literal 992 zcmb<-^>JflWMqH=Mh0dE1doBi0V-hvrZpJYf%4=4keMLN2GyJZQ6f022d)Ayf`Tfy@8_aUcdt!9f6!^8m~Fy%$d%E&4(GkKR@`2 zxtC`W<4MgE%?AuRy#IGzXuVYW*z#Vn82>gl{%yiQ4b86^JHq~VI5S#)E`Jpf9T$H% zBQ>iykqc-#u|TgRwW5SUFD0=gkwLFGqqwA~Bryrds?3GZP<~Nr4n!pZb7A2IQpUpY z@jtS1)RYDae{KLv4v<}q#BYMLK@28_HXsR# z0too{zaPjz@R=B<0r?tGSq7kch2U&ZJOh2>nO72$A6!zDnU}7Ymsp(35MNx9SX6>6 zj?C7}%P)z~OHEHK$t+7nkx0ob%S=g)&&kg(KoKu4Pb|P9nw?n?50YZYEly|1NiWHW b2QiXL)6!Cl7;;kcpzZ|ug%Ox0#h^3*J`I&; literal 0 HcmV?d00001 diff --git a/Strings32.nasm b/Strings32.nasm new file mode 100644 index 0000000..b61132a --- /dev/null +++ b/Strings32.nasm @@ -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 \ No newline at end of file diff --git a/bootloader.nasm b/bootloader.nasm index b2e8eee..238b2d4 100644 --- a/bootloader.nasm +++ b/bootloader.nasm @@ -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 diff --git a/demo b/demo new file mode 100644 index 0000000000000000000000000000000000000000..48e880d44b14c326bd11413fdb395d3903bf5e67 GIT binary patch literal 488 zcmb<-^>JflWMqH=CI)5(5U-(ug~J3$dqAa37!(+o7&I7Ipz>h#Ks5{?3{nHctRO)F zFcU&d1j+%iK2R8h*`V?u3I=v;{`LQVuPHlF*$Y{q;4XF`u@j_gH^|f-EI{IH!wwMp zY(scha6s#UN{(Y}y5Da!A7kwNy#MT(GiN#vHXmmE{`}x8=3bsjj3+fuG#@bN@c!R< zq4iSfW6OKRV*K0K__qlIH8j6w>> 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 \ No newline at end of file diff --git a/kernel.nasm b/kernel.nasm index fdced79..63a98f5 100644 --- a/kernel.nasm +++ b/kernel.nasm @@ -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