luciaos/entry.nasm
2022-09-14 16:50:44 -05:00

338 lines
6.1 KiB
NASM

[BITS 16]
global entry
entry:
cli ; no interrupts
xor ax,ax
mov ds, ax
lgdt [gdt_desc] ; load gdt register
mov eax, cr0 ; set pmode bit
or al, 1
mov cr0, eax
jmp 08h:Pmodecode
[BITS 32]
Pmodecode:
mov ax, 0x10 ; set up segments
mov ds, ax
mov es, ax
mov ss, ax
mov ebp, 0x400000
mov esp, ebp
mov eax, 0x1f001f00
mov ecx, (80*25)/2
mov edi, 0xb8000
rep stosd
call start
hlt_loop:
hlt
jmp hlt_loop
setup_paging:
mov ecx, 1024*3 ; 3K?
xor eax, eax
mov edi, 0x1000
rep stosd ; zero first 3K for some reason
mov edi, 0x4000
mov eax, 0x800007 ; 8MB + 7
std ; fill backwards
.fill:
stosd
sub eax, 0x1000
jge .fill
cld ; fix direction
mov dword [0x0000], 0x2000 + 7
mov dword [0x0004], 0x3000 + 7
mov eax, 0x1000
mov cr3, eax ; page dir start 0x1000
mov eax, cr0
or eax, 0x80000000
mov cr0, eax ; set paging bit
ret ; flushes pre-fetch queue
[BITS 16]
real_hexprint:
xor cx, cx
mov bl, al
shr al, 4
jmp .donibble
.nibble2:
mov al, bl
inc cx
.donibble:
and al, 0x0F
cmp al, 0x0A
jl .noadjust
add al, 'A' - '0' - 10
.noadjust:
add al, '0'
mov ah, 0x1f
stosw
test cx, cx
jz .nibble2
ret
real_printword:
mov dx, ax
mov al, ah
call real_hexprint
mov ax, dx
call real_hexprint
ret
extern v86Code
v86Code:
mov ax, 0xb814
mov es, ax
mov di, 20
mov ax, sp
call real_printword
add di, 2
mov ax, ds
call real_printword
add di, 2
mov ax, cs
call real_printword
.loop:
inc byte [0]
;mov ax, 0x1111
;mov ds, ax
;mov ax, 0x2222
;mov es, ax
;mov ax, 0x3333
;mov fs, ax
;mov ax, 0x4444
;mov gs, ax
;mov ax, 0x5555
;mov ss, ax
;mov ax, 0x6666
;mov sp, ax
int 3
;jmp .loop
mov ax, 0x13
int 0x10
int 0x30 ; exit
jmp $
extern real_test
real_test:
nop
nop
nop
jmp $
[BITS 32]
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
global enter_v86
enter_v86:
mov ebp, esp ; save stack pointer
push dword [ebp+4] ; ss
push dword [ebp+8] ; esp
pushfd ; eflags
or dword [esp], (1 << 17) ; set VM flags
;or dword [esp], (3 << 12) ; IOPL 3
push dword [ebp+12] ; cs
push dword [ebp+16] ; eip
iret
user_test:
mov dword [0xb8000], 0x0f000f00 | 'U' | 's' << 16
mov dword [0xb8004], 0x0f000f00 | 'e' | 'r' << 16
mov dword [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
mov word [0xb8010], 0x0f00 | '!'
mov edi, 0xA0000
xor eax, eax
.loop:
mov cx, 320
rep stosb
inc al
cmp eax, 200
jl .loop
xor ebx, ebx
div bl
global jmp_usermode_test
jmp_usermode_test:
mov ax, 0x20 | 3
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push 0x20 | 3
push eax
pushfd
push 0x18 | 3
push user_test
iret
extern unhandled_handler
unhandled_handler:
mov ax, 0x10
mov ds, ax
mov dword [0xb8000], 0x0f000f00 | 'E' | 'R' << 16
mov dword [0xb8004], 0x0f000f00 | 'R' | 'O' << 16
mov dword [0xb8008], 0x0f000f00 | 'R' | '!' << 16
.hlt:
hlt
jmp .hlt
extern gpf_handler_v86
global gpfHandler
gpfHandler:
iret
mov ax, 0x10
mov ds, ax
;jmp gpf_handler_v86
mov word [0xb8000], 0x0f00 | 'G'
mov word [0xb8002], 0x0f00 | 'P'
mov word [0xb8004], 0x0f00 | 'F'
.hlt:
hlt
jmp .hlt
scancodesToAscii: db 0, 0 ; 0x00 - 0x01
db "1234567890" ; 0x02 - 0x0B
db "-=" ; 0x0C - 0x0D
db 0, 0 ; 0x0E - 0x0F
db "qwertyuiop[]" ; 0x10 - 0x1B
db 0, 0 ; 0x1C - 0x1D
db "asdfghjkl;'`" ; 0x1E - 0x29
db 0 ; 0x2A
db "\zxcvbnm,./" ; 0x2B - 0x35
db 0 ; 0x36
db '*' ; 0x37
db 0 ; 0x38
db ' ' ; 0x39
db 'C'
scancodesToAsciiEnd:
cursorCurrent: dd 0xb8000 + (80*6*2)
global keyboardHandler
keyboardHandler:
push eax
push ebx
push ds
mov ax, 0x10
mov ds, ax
xor eax, eax
in al, 0x60
cmp eax, 0x3A
jg .done
mov al, [scancodesToAscii+eax]
test al, al
jz .done
mov ebx, [cursorCurrent]
mov byte [ebx], al
add dword [cursorCurrent], 2
mov byte [KBDWAIT], 1
.done:
mov al, 0x20
out 0x20, al
pop ds
pop ebx
pop eax
iret
KBDWAIT: db 0
global kbd_wait
kbd_wait:
mov byte [KBDWAIT], 0
.loop:
hlt
xor eax, eax
mov al, [KBDWAIT]
test eax, eax
jz .loop
ret
global timerHandler
timerHandler:
push eax
push ds
mov ax, 0x10
mov ds, ax
inc byte [(0xb8000 + (80*8*2))]
mov al, 0x20
out 0x20, al
pop ds
pop eax
iret
global picInit
picInit:
mov al, 0x11 ; initialization sequence
out 0x20, al ; send to 8259A-1
jmp $+2
jmp $+2
out 0xA0, al ; and to 8259A-2
jmp $+2
jmp $+2
mov al, 0x20 ; start of hardware ints (0x20)
out 0x21, al
jmp $+2
jmp $+2
mov al, 0x28 ; start of hardware ints 2 (0x28)
out 0xA1, al
jmp $+2
jmp $+2
mov al, 0x04 ; 8259-1 is master
out 0x21, al
jmp $+2
jmp $+2
mov al, 0x02 ; 8259-2 is slave
out 0xA1, al
jmp $+2
jmp $+2
mov al, 0x01 ; 8086 mode for both
out 0x21, al
jmp $+2
jmp $+2
out 0xA1, al
jmp $+2
jmp $+2
mov al, 0xFF ; all interrupts off for now
out 0x21, al
jmp $+2
jmp $+2
out 0xA1, al
ret
global flushTSS
flushTSS:
mov ax, 0x28
ltr ax
ret
extern tss_data
extern start
gdt_desc:
dw gdt_end - gdt
dd gdt
gdt:
gdt_null: dq 0
gdt_code: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
db 0 ; bits 16-23 base address
db 10011010b ; access byte
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
db 0 ; bits 24-31 base address
gdt_data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
db 0 ; bits 16-23 base address
db 10010010b ; access byte
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
db 0 ; bits 24-31 base address
gdt_r3code: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
db 0 ; bits 16-23 base address
db 0xFA ; access byte
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
db 0 ; bits 24-31 base address
gdt_r3data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
db 0 ; bits 16-23 base address
db 0xF2 ; access byte
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
db 0 ; bits 24-31 base address
gdt_tss: dw 0x2080, 0x0000;26*4, tss_data ; bits 0-15 limit (4GB), bits 0-15 base address
db 0x2 ; bits 16-23 base address
db 0x89 ; access byte
db 00000000b ; bits 16-19 limit (4GB), 4 bits flags
db 0 ; bits 24-31 base address
gdt_end: