mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
ppc
This commit is contained in:
parent
f1b3bf129b
commit
8ec0bffa53
1655
fs/command.ppc
Normal file
1655
fs/command.ppc
Normal file
File diff suppressed because it is too large
Load Diff
1629
fs/doskrnl.ppc
Normal file
1629
fs/doskrnl.ppc
Normal file
File diff suppressed because it is too large
Load Diff
995
fs/hello.ppc
Normal file
995
fs/hello.ppc
Normal file
@ -0,0 +1,995 @@
|
||||
# 1 "hello.k"
|
||||
# 1 "<built-in>"
|
||||
# 1 "<command-line>"
|
||||
# 31 "<command-line>"
|
||||
# 1 "/usr/include/stdc-predef.h" 1 3 4
|
||||
# 32 "<command-line>" 2
|
||||
# 1 "hello.k"
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
start:
|
||||
jmp main
|
||||
|
||||
# 1 "crt/crt.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; Limits
|
||||
;
|
||||
# 31 "crt/crt.k"
|
||||
;
|
||||
; Magic numbers
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
;
|
||||
; CRT librairies
|
||||
;
|
||||
|
||||
# 1 "./crt/sys.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; SHUTDOWN syscall
|
||||
;
|
||||
; End virtual machine
|
||||
;
|
||||
Sys.Shutdown := 0x00
|
||||
|
||||
;
|
||||
; EXIT syscall
|
||||
;
|
||||
; Return to COMMAND.COM
|
||||
;
|
||||
Sys.Exit := 0x01
|
||||
|
||||
;
|
||||
; EXEC syscall
|
||||
;
|
||||
; IN
|
||||
; ax0 = new RIP to load
|
||||
; ax1 = frame ID to switch to
|
||||
;
|
||||
; New frame ID must be higher than current
|
||||
; frame ID, and cannot be below 5
|
||||
;
|
||||
; New CR1 is set so that new RIP corresponds to 1MB
|
||||
;
|
||||
Sys.ExecuteInFrame := 0x02
|
||||
|
||||
; FIND syscalls
|
||||
;
|
||||
; Find file on disk
|
||||
;
|
||||
; IN
|
||||
; ax0 = address of name buffer
|
||||
; ax1 = size of name buffer
|
||||
;
|
||||
; OUT
|
||||
; rax = # of bytes written in name buffer
|
||||
; rdx = size of file
|
||||
;
|
||||
;
|
||||
Sys.FindFirst := 0x20
|
||||
Sys.FindNext := 0x21
|
||||
|
||||
;
|
||||
; OPEN syscall
|
||||
;
|
||||
; IN
|
||||
; ax0 = name string
|
||||
;
|
||||
; OUT
|
||||
; rax = handle of file, or <0 if couldn't open
|
||||
;
|
||||
Sys.OpenFile := 0x30
|
||||
|
||||
;
|
||||
; CREATE syscall
|
||||
;
|
||||
; IN
|
||||
; ax0 = name string
|
||||
;
|
||||
; OUT
|
||||
; rax = 0 on success, or <0 if couldn't open
|
||||
;
|
||||
Sys.CreateFile := 0x31
|
||||
|
||||
;
|
||||
; REMOVE syscall
|
||||
;
|
||||
; IN
|
||||
; ax0 = name string
|
||||
;
|
||||
; OUT
|
||||
; rax = 0 on success, or <0 if couldn't open
|
||||
;
|
||||
Sys.RemoveFile := 0x32
|
||||
|
||||
;
|
||||
; CLOSE syscall
|
||||
;
|
||||
; IN
|
||||
; ax0 = file handle
|
||||
;
|
||||
Sys.CloseFile := 0x35
|
||||
|
||||
;
|
||||
; READ syscall
|
||||
;
|
||||
; IN
|
||||
; ax0 = file handle
|
||||
; ax1 = buffer address
|
||||
; ax2 = buffer size
|
||||
;
|
||||
; OUT
|
||||
; rax = number of bytes read, <0 on error
|
||||
;
|
||||
Sys.ReadFile := 0x38
|
||||
|
||||
; Halt mode
|
||||
Sys.EnterHaltMode := 0x999
|
||||
# 43 "crt/crt.k" 2
|
||||
# 1 "./crt/str.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; int strnlen(char *, int)
|
||||
;
|
||||
strnlen:
|
||||
mov rcx, ax1
|
||||
scasb ax0, zero
|
||||
|
||||
sub rax, ax1, rcx
|
||||
ret
|
||||
|
||||
;
|
||||
; int strlen(char *)
|
||||
;
|
||||
strlen:
|
||||
mov rcx, 0x7AFFFFFF
|
||||
mov rdx, rcx
|
||||
scasb ax0, zero
|
||||
|
||||
sub rax, rdx, rcx
|
||||
ret
|
||||
|
||||
;
|
||||
; void strcpy(char *, const char *)
|
||||
;
|
||||
strcpy:
|
||||
.l:
|
||||
mov rcx, b[ax1]
|
||||
mov b[ax0], rcx
|
||||
|
||||
jrcxz .r
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
; void strncpy(char *, const char *, int)
|
||||
;
|
||||
strncpy:
|
||||
mov rcx, ax2
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
; void strnzcpy(char *, const char *, int)
|
||||
;
|
||||
strnzcpy:
|
||||
mov rcx, ax2
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
mov rax, b[ax1]
|
||||
mov b[ax0], rax
|
||||
|
||||
jraxz .r
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
|
||||
loop .l
|
||||
|
||||
.z:
|
||||
nul b[ax0]
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
; int strcmp(const char *str1, const char *str2)
|
||||
;
|
||||
; Returns:
|
||||
; 0 if the contents of both strings are equal
|
||||
; >0 if the first character that does not match has a greater value in str1 than in str2
|
||||
; <0 if the first character that does not match has a lower value in str1 than in str2
|
||||
;
|
||||
strcmp:
|
||||
nul rsi
|
||||
.l:
|
||||
movzx rax, b[ax0+rsi]
|
||||
movzx rdx, b[ax1+rsi]
|
||||
|
||||
bne rax, rdx, .r
|
||||
|
||||
; both zero?
|
||||
add rcx, rax, rdx
|
||||
jrcxz .r
|
||||
|
||||
inc rsi
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
sub rax, rdx
|
||||
ret
|
||||
|
||||
;
|
||||
; int strncmp(const char *str1, const char *str2, int maxn)
|
||||
;
|
||||
strncmp:
|
||||
mov rcx, ax2
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
movzx rax, b[ax0]
|
||||
movzx rdx, b[ax1]
|
||||
|
||||
bne rax, rdx, .r
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
sub rax, rdx
|
||||
ret
|
||||
|
||||
;
|
||||
; char *strchrnul(const char *str, int ch)
|
||||
;
|
||||
strchrnul:
|
||||
mov rcx, 0x7AFFFFFF
|
||||
scasb ax0, ax1
|
||||
|
||||
mov rax, ax0
|
||||
ret
|
||||
|
||||
;
|
||||
; char *strchr(const char *str, int ch)
|
||||
;
|
||||
strchr:
|
||||
mov rcx, 0x7AFFFFFF
|
||||
scasb ax0, ax1
|
||||
|
||||
bnz b[ax0], .r
|
||||
nul rax
|
||||
ret
|
||||
|
||||
.r:
|
||||
mov rax, ax0
|
||||
ret
|
||||
|
||||
;
|
||||
; void strrev(char *buf, const char *str)
|
||||
;
|
||||
; buf and src must NOT overlap
|
||||
;
|
||||
strrev:
|
||||
bzr b[ax1], .z
|
||||
|
||||
; save str's location
|
||||
mov rsi, ax1
|
||||
|
||||
; go to str's end, just before
|
||||
; the null terminator
|
||||
mov rcx, 0x7AFFFFFF
|
||||
scasb ax1, zero
|
||||
dec ax1
|
||||
|
||||
.l:
|
||||
; copy, going backward though str
|
||||
; and forward through buf
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
beq ax1, rsi, .r
|
||||
|
||||
inc ax0
|
||||
dec ax1
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
nul b[ax0+1]
|
||||
ret
|
||||
|
||||
.z:
|
||||
nul b[ax0]
|
||||
ret
|
||||
|
||||
;
|
||||
; void strrev2(char *str)
|
||||
;
|
||||
; Inverses str
|
||||
;
|
||||
strrev2:
|
||||
bzr b[ax0], .r
|
||||
|
||||
mov ax1, ax0
|
||||
|
||||
; go to str's end, just before
|
||||
; the null terminator
|
||||
mov rcx, 0x7AFFFFFF
|
||||
scasb ax1, zero
|
||||
dec ax1
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.l:
|
||||
blteu ax1, ax0, .r
|
||||
|
||||
xchg b[ax0], b[ax1]
|
||||
|
||||
inc ax0
|
||||
dec ax1
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
# 44 "crt/crt.k" 2
|
||||
# 1 "./crt/mem.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; void memcpy(void *, const void *, int)
|
||||
;
|
||||
memcpy:
|
||||
mov rcx, ax2
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
sub rdx, ax2, rcx
|
||||
mov b[ax0+rdx], b[ax1+rdx]
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
; void memzero(void *, int)
|
||||
;
|
||||
memzero:
|
||||
mov rcx, ax1
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
nul b[ax0]
|
||||
inc ax0
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
# 45 "crt/crt.k" 2
|
||||
# 1 "./crt/time.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; struct TIME
|
||||
; {
|
||||
; byte sec; +0 (0-59)
|
||||
; byte min; +1 (0-59)
|
||||
; byte hour; +2 (0-23)
|
||||
; byte mday; +3 (0-31)
|
||||
; byte month; +4 (0-11)
|
||||
; byte; +5 (pad)
|
||||
; word year; +6 (0-65536)
|
||||
; word yday; +8 (0-365)
|
||||
; word; +10 (pad)
|
||||
; dword; +12 (pad)
|
||||
; } 16 bytes
|
||||
;
|
||||
|
||||
;
|
||||
; int DaysInYear(int year)
|
||||
;
|
||||
DaysInYear:
|
||||
mov rax, 365
|
||||
|
||||
; divisible by 4?
|
||||
rem rcx, ax0, 4
|
||||
jrcxnz .end
|
||||
|
||||
; divisible by 100?
|
||||
rem rcx, ax0, 100
|
||||
jrcxnz .leap
|
||||
|
||||
; divisible by 400?
|
||||
rem rcx, ax0, 400
|
||||
jrcxnz .end
|
||||
|
||||
.leap:
|
||||
inc rax, 1
|
||||
|
||||
.end:
|
||||
ret
|
||||
|
||||
;
|
||||
; TIME *GetTimeUTC(void)
|
||||
;
|
||||
GetTimeUTC:
|
||||
ytime
|
||||
|
||||
mov rdi, .buf
|
||||
|
||||
; seconds
|
||||
rem rsi, rax, 60
|
||||
mov b[rdi], rsi
|
||||
|
||||
; minutes
|
||||
div rsi, rax, 60
|
||||
rem rsi, 60
|
||||
mov b[rdi+1], rsi
|
||||
|
||||
; hours
|
||||
div rsi, rax, 3600
|
||||
rem rsi, 24
|
||||
mov b[rdi+2], rsi
|
||||
|
||||
; month days
|
||||
div rsi, rax, 3600*24
|
||||
mov b[rdi+3], rsi
|
||||
|
||||
; month
|
||||
mov b[rdi+4], rbx
|
||||
|
||||
; years
|
||||
mov w[rdi+6], rcx
|
||||
|
||||
;
|
||||
; ydays (TODO)
|
||||
;
|
||||
|
||||
mov rax, .buf
|
||||
ret
|
||||
|
||||
.buf = [24]
|
||||
# 46 "crt/crt.k" 2
|
||||
|
||||
# 1 "./crt/fmt/ltostr.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; void itoa(char *buf, int num, int base)
|
||||
;
|
||||
itoa:
|
||||
mov ax3, 1
|
||||
jmp ltostr
|
||||
|
||||
;
|
||||
; void utoa(char *buf, int num, int base)
|
||||
;
|
||||
utoa:
|
||||
nul ax3
|
||||
jmp ltostr
|
||||
|
||||
;
|
||||
; void ltostr(char *buf, int num, int base, bool signed)
|
||||
;
|
||||
ltostr:
|
||||
mov rax, ax0
|
||||
nul rcx
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
bltu ax2, 2, .bad
|
||||
bltu 36, ax2, .bad
|
||||
|
||||
; deal with zero
|
||||
bzr ax1, .is_zero
|
||||
|
||||
; deal with base 10 signedness
|
||||
|
||||
bzr ax3, .conv
|
||||
bne ax2, 10, .conv ; base 10
|
||||
|
||||
shr rcx, ax1, 63 ; extract ax1 sign
|
||||
jrcxz .conv
|
||||
|
||||
neg ax1 ; NEG if negative
|
||||
|
||||
; main loop
|
||||
.conv:
|
||||
bzr ax1, .fini
|
||||
|
||||
rem rdx, ax1, ax2 ; ax1 % base
|
||||
|
||||
blt 9, rdx, .nondec ; rdx > 9 ?
|
||||
|
||||
inc rdx, '0'
|
||||
jmp .next
|
||||
|
||||
.nondec:
|
||||
inc rdx, 55 ; 'A' - 10
|
||||
|
||||
.next:
|
||||
mov b[ax0], rdx
|
||||
|
||||
inc ax0
|
||||
|
||||
div ax1, ax2
|
||||
jmp .conv
|
||||
|
||||
; add minus flag, null-terminate and reverse
|
||||
.fini:
|
||||
jrcxz .cxz
|
||||
mov b[ax0], '-'
|
||||
inc ax0
|
||||
|
||||
.cxz:
|
||||
nul b[ax0]
|
||||
|
||||
call strrev2, rax
|
||||
ret
|
||||
|
||||
;
|
||||
; exceptional cases
|
||||
;
|
||||
.bad:
|
||||
mov b[ax0], 0
|
||||
ret
|
||||
|
||||
.is_zero:
|
||||
mov b[ax0], 48 ; '0'
|
||||
mov b[ax0+1], 0
|
||||
ret
|
||||
# 48 "crt/crt.k" 2
|
||||
# 1 "./crt/fmt/strtol.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; int strtol(const char *str, int base)
|
||||
;
|
||||
; rax = integer extracted from str
|
||||
; rdx = pointer to first invalid byte
|
||||
;
|
||||
strtol:
|
||||
mov ax2, 1
|
||||
jmp strtoq
|
||||
|
||||
;
|
||||
; int strtoul(const char *str, int base)
|
||||
;
|
||||
; rax = integer extracted from str
|
||||
; rdx = pointer to first invalid byte
|
||||
;
|
||||
strtoul:
|
||||
nul ax2
|
||||
jmp strtoq
|
||||
|
||||
;
|
||||
; int strtoq(const char *str, int base, bool signed)
|
||||
;
|
||||
; guesses base when 'base'=0
|
||||
;
|
||||
strtoq:
|
||||
nul rax, rsi
|
||||
mov rdx, ax0
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
beq ax1, 1, .bad
|
||||
bltu 36, ax1, .bad
|
||||
|
||||
; empty string?
|
||||
bzr b[rdx], .done
|
||||
|
||||
.skip_spc:
|
||||
bne b[rdx], ' ', .no_spc
|
||||
inc rdx
|
||||
jmp .skip_spc
|
||||
|
||||
.no_spc:
|
||||
; skip +
|
||||
bne b[rdx], '+', .no_plus
|
||||
inc rdx
|
||||
|
||||
.no_plus:
|
||||
; unsigned?
|
||||
bzr ax2, .unsigned
|
||||
|
||||
; parse '-'
|
||||
bne b[rdx], '-', .unsigned
|
||||
inc rdx
|
||||
mov rsi, 1
|
||||
|
||||
.unsigned:
|
||||
; base 0
|
||||
bzr ax1, .base_0
|
||||
|
||||
; base prefix?
|
||||
bne b[rdx], '0', .main_loop
|
||||
|
||||
inc rdx
|
||||
movzx rcx, b[rdx]
|
||||
|
||||
; "0x"/"0b" prefix
|
||||
jrcxz .done ; "0"
|
||||
beq rcx, 'x', .parsed_0x
|
||||
beq rcx, 'b', .parsed_0b
|
||||
|
||||
; may be octal, but we don't care
|
||||
; we accept "0110101010" (despite base=2) for instance
|
||||
jmp .main_loop
|
||||
|
||||
.parsed_0x:
|
||||
; are we in base 16?
|
||||
; if not, leave rax = 0 and *rdx = 'x'
|
||||
bne ax1, 16, .done
|
||||
; else
|
||||
inc rdx, 1
|
||||
jmp .main_loop
|
||||
|
||||
.parsed_0b:
|
||||
; are we in base 2?
|
||||
; if not, leave rax = 0 and *rdx = 'b'
|
||||
bne ax1, 2, .done
|
||||
; else
|
||||
inc rdx
|
||||
jmp .main_loop
|
||||
|
||||
.base_0:
|
||||
; guess base
|
||||
|
||||
beq b[rdx], '0', .b0_not10
|
||||
|
||||
; must be base 10
|
||||
mov ax1, 10
|
||||
jmp .main_loop
|
||||
|
||||
.b0_not10:
|
||||
inc rdx
|
||||
|
||||
bne b[rdx], 'x', .b0_not16
|
||||
inc rdx
|
||||
mov ax1, 16
|
||||
jmp .main_loop
|
||||
|
||||
.b0_not16:
|
||||
bne b[rdx], 'b', .b0_not2
|
||||
inc rdx
|
||||
mov ax1, 2
|
||||
jmp .main_loop
|
||||
|
||||
.b0_not2:
|
||||
; take octal by default
|
||||
mov ax1, 8
|
||||
|
||||
.main_loop:
|
||||
movzx rcx, b[rdx]
|
||||
inc rdx
|
||||
|
||||
; between 0 and 9?
|
||||
bltu rcx, '0', .done
|
||||
bltu '9', rcx, .not_digit10
|
||||
|
||||
; yes
|
||||
sub rcx, '0'
|
||||
jmp .next
|
||||
|
||||
.not_digit10:
|
||||
bltu rcx, 'A', .done
|
||||
bltu 'Z', rcx, .not_digitAZ
|
||||
|
||||
sub rcx, 55 ; 'A' - 10
|
||||
jmp .next
|
||||
|
||||
.not_digitAZ:
|
||||
bltu rcx, 'a', .done
|
||||
bltu 'z', rcx, .done
|
||||
|
||||
sub rcx, 87 ; 'a' - 10
|
||||
jmp .next
|
||||
|
||||
.next:
|
||||
; too large for base?
|
||||
blteu ax1, rcx, .done
|
||||
|
||||
mul rax, ax1
|
||||
inc rax, rcx
|
||||
jmp .main_loop
|
||||
|
||||
.done:
|
||||
; negative?
|
||||
bzr rsi, .r
|
||||
|
||||
; yes
|
||||
neg rax
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
.bad:
|
||||
ret
|
||||
# 49 "crt/crt.k" 2
|
||||
# 1 "./crt/fmt/doprnt.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; typedef int (*PUTC)(int ch)
|
||||
; int doprnt(PUTC putc, int n, const char *fmt, va_list ap)
|
||||
;
|
||||
doprnt:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
push r12, r13, r14
|
||||
push r15, r16, r17
|
||||
|
||||
mov r12, ax2 ; fmt
|
||||
mov r14, ax3 ; va_list
|
||||
mov r15, ax1 ; n
|
||||
mov r17, ax0 ; putc
|
||||
nul r16 ; return value
|
||||
|
||||
.main_loop:
|
||||
; find '%' or null-terminator
|
||||
mov rcx, 0x7AFFFFFF
|
||||
mov r13, r12
|
||||
scasb r13, '%'
|
||||
|
||||
; everything below r13 is a regular character; print it
|
||||
.print_regular:
|
||||
beq r12, r13, .check_modf
|
||||
|
||||
call .doput, b[r12]
|
||||
|
||||
inc r12, 1
|
||||
jmp .print_regular
|
||||
|
||||
.check_modf:
|
||||
; did we find a '%' ?
|
||||
; if not, then we found fmt's null-terminator; we're done
|
||||
bne b[r12], '%', .epilogue
|
||||
|
||||
; we did find a modifier / '%'
|
||||
mov rax, b[r12+1]
|
||||
inc r12, 2
|
||||
|
||||
beq rax, 's', .modf_s
|
||||
beq rax, 'c', .modf_c
|
||||
beq rax, 'p', .modf_p
|
||||
beq rax, 'x', .modf_x
|
||||
beq rax, 'd', .modf_d
|
||||
beq rax, 'o', .modf_o
|
||||
beq rax, 'b', .modf_b
|
||||
beq rax, '%', .modf_percent
|
||||
|
||||
; unrecognized
|
||||
jmp .bad_modifier
|
||||
|
||||
.modf_s:
|
||||
; get string address
|
||||
mov r13, q[r14]
|
||||
inc r14, 8
|
||||
|
||||
bzr r13, .nullstring
|
||||
|
||||
.print_string:
|
||||
movzx ax0, b[r13]
|
||||
bzr ax0, .main_loop
|
||||
|
||||
inc r13
|
||||
call .doput
|
||||
|
||||
jmp .print_string
|
||||
|
||||
.modf_c:
|
||||
call .doput, q[r14]
|
||||
inc r14, 8
|
||||
|
||||
jmp .main_loop
|
||||
|
||||
.modf_p:
|
||||
call .doput, '0'
|
||||
call .doput, 'x'
|
||||
; Fallthrough
|
||||
|
||||
.modf_x:
|
||||
mov ax2, 16
|
||||
jmp .print_number
|
||||
|
||||
.modf_d:
|
||||
mov ax2, 10
|
||||
jmp .print_number
|
||||
|
||||
.modf_o:
|
||||
mov ax2, 8
|
||||
jmp .print_number
|
||||
|
||||
.modf_b:
|
||||
mov ax2, 2
|
||||
jmp .print_number
|
||||
|
||||
.print_number:
|
||||
; allocate itoa conversion buffer
|
||||
sub rsp, 80
|
||||
mov r13, rsp
|
||||
|
||||
; assume modifier already set up ax2
|
||||
call itoa, rsp, q[r14]
|
||||
inc r14, 8
|
||||
|
||||
.print_itoa_buf:
|
||||
movzx ax0, b[r13]
|
||||
|
||||
bzr ax0, .pib_end_loop
|
||||
inc r13
|
||||
|
||||
call .doput
|
||||
jmp .print_itoa_buf
|
||||
|
||||
.pib_end_loop:
|
||||
inc rsp, 80
|
||||
jmp .main_loop
|
||||
|
||||
.modf_percent:
|
||||
call .doput, '%'
|
||||
jmp .main_loop
|
||||
|
||||
.bad_modifier:
|
||||
; print "%?" to clearly indicate that something is wrong
|
||||
call .doput, '%'
|
||||
call .doput, '?'
|
||||
|
||||
jmp .main_loop
|
||||
|
||||
.nullstring:
|
||||
; %s was passed a NULL
|
||||
call .doput, '('
|
||||
call .doput, 'n'
|
||||
call .doput, 'u'
|
||||
call .doput, 'l'
|
||||
call .doput, 'l'
|
||||
call .doput, ')'
|
||||
|
||||
jmp .main_loop
|
||||
|
||||
.epilogue:
|
||||
mov rax, r16
|
||||
|
||||
pop r17, r16
|
||||
pop r15, r14
|
||||
pop r13, r12
|
||||
|
||||
leave
|
||||
ret
|
||||
;
|
||||
; prints ax0
|
||||
;
|
||||
.doput:
|
||||
; update print count
|
||||
inc r16
|
||||
|
||||
; if n==0, don't print
|
||||
; we follow the C convention that sprintf()-like functions
|
||||
; should return the number of characters that would have
|
||||
; been printed/written if 'n' were big enough
|
||||
bzr r15, .r
|
||||
|
||||
; decrement n and print
|
||||
dec r15
|
||||
call r17
|
||||
|
||||
; did putc fail?
|
||||
jraxz .r
|
||||
|
||||
; yes, so artificially set n=0
|
||||
nul r15
|
||||
|
||||
.r:
|
||||
ret
|
||||
# 50 "crt/crt.k" 2
|
||||
# 1 "./crt/fmt/printf.k" 1
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; int putc(int ch)
|
||||
;
|
||||
putc:
|
||||
prn ax0
|
||||
nul rax
|
||||
ret
|
||||
|
||||
;
|
||||
; int printf(const char *fmt, ...)
|
||||
;
|
||||
printf:
|
||||
mov ax2, ax0
|
||||
mov ax0, putc
|
||||
mov ax1, 0x7AFFFFFF
|
||||
add ax3, rsp, 8
|
||||
jmp doprnt
|
||||
|
||||
;
|
||||
; int nprintf(const char *fmt, int n, ...)
|
||||
;
|
||||
nprintf:
|
||||
mov ax2, ax0
|
||||
mov ax0, putc
|
||||
add ax3, rsp, 8
|
||||
jmp doprnt
|
||||
|
||||
;
|
||||
; Print a string
|
||||
; Guaranteed to only affect rcx and ax0
|
||||
;
|
||||
print:
|
||||
.l:
|
||||
movzx rax, b[ax0]
|
||||
jraxz .r
|
||||
|
||||
prn rax
|
||||
inc ax0
|
||||
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
; Print exactly ax1 characters
|
||||
;
|
||||
nprint:
|
||||
mov rcx, ax1
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
prn b[ax0]
|
||||
inc ax0
|
||||
loop .l
|
||||
.r:
|
||||
ret
|
||||
# 51 "crt/crt.k" 2
|
||||
|
||||
exit:
|
||||
mov rax, Sys.Exit
|
||||
trap 0
|
||||
|
||||
abort:
|
||||
crash
|
||||
# 8 "hello.k" 2
|
||||
|
||||
main:
|
||||
mov rsp, 0x104000
|
||||
nul rbp
|
||||
|
||||
call print, .hellow
|
||||
|
||||
jmp exit
|
||||
|
||||
.hellow = "Hello World!\n"
|
@ -5,12 +5,15 @@ all: dos
|
||||
|
||||
KODIR=../fs
|
||||
KSDIR=../vm/ob
|
||||
KPDIR=../vm/ob
|
||||
|
||||
KSRC = $(shell ls *.k)
|
||||
KPPC = $(patsubst %.k,$(KODIR)/%.ppc,$(KSRC))
|
||||
KCOM = $(patsubst %.k,$(KODIR)/%.com,$(KSRC))
|
||||
|
||||
$(KODIR)/%.com: %.k
|
||||
@../as/k-as.py $< 0x100000 $@ $(patsubst %.k,$(KSDIR)/%.sym,$<)
|
||||
@cpp -I. -x assembler-with-cpp $< > $(patsubst %.k,$(KODIR)/%.ppc,$<)
|
||||
@../as/k-as.py $(patsubst %.k,$(KODIR)/%.ppc,$<) 0x100000 $@ $(patsubst %.k,$(KSDIR)/%.sym,$<)
|
||||
|
||||
dos: $(KCOM)
|
||||
|
||||
|
16
ka/command.k
16
ka/command.k
@ -4,16 +4,16 @@
|
||||
cmdstart:
|
||||
jmp start
|
||||
|
||||
include "crt/crt.k"
|
||||
#include "crt/crt.k"
|
||||
|
||||
CMDCOM_CODE := 0x100000 ; 1MB
|
||||
CMDCOM_STACK := 0x104000 ; + 16KB
|
||||
#define CMDCOM_CODE 0x100000 ; 1MB
|
||||
#define CMDCOM_STACK 0x104000 ; + 16KB
|
||||
|
||||
; COMMAND.COM guarantees that programs
|
||||
; are always loaded on a 16KB boundary
|
||||
; This is guaranteed to be the case
|
||||
; in all future versions as well
|
||||
FILE_LOADP := 0x108000 ; + 32KB
|
||||
#define FILE_LOADP 0x108000 ; + 32KB
|
||||
|
||||
start:
|
||||
mov rsp, CMDCOM_STACK
|
||||
@ -53,7 +53,7 @@ main:
|
||||
call memzero, argv0, argbuf.size
|
||||
nul q[argv1pos]
|
||||
|
||||
# call nprint, argv0, argbuf.size
|
||||
; call nprint, argv0, argbuf.size
|
||||
|
||||
; iterator through argbuf
|
||||
nul rcx
|
||||
@ -224,9 +224,9 @@ main:
|
||||
; call builtins
|
||||
;
|
||||
|
||||
include "usr/cmd-dir.k"
|
||||
include "usr/cmd-exec.k"
|
||||
include "usr/cmd-fsmisc.k"
|
||||
#include "usr/cmd-dir.k"
|
||||
#include "usr/cmd-exec.k"
|
||||
#include "usr/cmd-fsmisc.k"
|
||||
|
||||
.handle_CLS:
|
||||
prn PRN_CLEAR
|
||||
|
56
ka/crt/crt.k
56
ka/crt/crt.k
@ -5,49 +5,49 @@
|
||||
; Limits
|
||||
;
|
||||
|
||||
CHAR_MIN := 0x80
|
||||
SHRT_MIN := 0x8000
|
||||
INT_MIN := 0x80000000
|
||||
LONG_MIN := 0x8000000000000000
|
||||
#define CHAR_MIN 0x80
|
||||
#define SHRT_MIN 0x8000
|
||||
#define INT_MIN 0x80000000
|
||||
#define LONG_MIN 0x8000000000000000
|
||||
|
||||
XCHAR_MIN := 0xFFFFFFFFFFFFFF80
|
||||
XSHRT_MIN := 0xFFFFFFFFFFFF8000
|
||||
XINT_MIN := 0xFFFFFFFF80000000
|
||||
#define XCHAR_MIN 0xFFFFFFFFFFFFFF80
|
||||
#define XSHRT_MIN 0xFFFFFFFFFFFF8000
|
||||
#define XINT_MIN 0xFFFFFFFF80000000
|
||||
|
||||
CHAR_MAX := 0x7F
|
||||
SHRT_MAX := 0x7FFF
|
||||
INT_MAX := 0x7FFFFFFF
|
||||
LONG_MAX := 0x7FFFFFFFFFFFFFFF
|
||||
#define CHAR_MAX 0x7F
|
||||
#define SHRT_MAX 0x7FFF
|
||||
#define INT_MAX 0x7FFFFFFF
|
||||
#define LONG_MAX 0x7FFFFFFFFFFFFFFF
|
||||
|
||||
BYTE_MAX := 0xFF
|
||||
WORD_MAX := 0xFFFF
|
||||
LWORD_MAX := 0xFFFFFFFF
|
||||
QWORD_MAX := 0xFFFFFFFFFFFFFFFF
|
||||
#define BYTE_MAX 0xFF
|
||||
#define WORD_MAX 0xFFFF
|
||||
#define LWORD_MAX 0xFFFFFFFF
|
||||
#define QWORD_MAX 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
FNAME_MAX := 0x80
|
||||
FILE_MAXSZ := 0x8000
|
||||
STRLEN_MAX := 0x7AFFFFFF
|
||||
#define FNAME_MAX 0x80
|
||||
#define FILE_MAXSZ 0x8000
|
||||
#define STRLEN_MAX 0x7AFFFFFF
|
||||
|
||||
;
|
||||
; Magic numbers
|
||||
;
|
||||
|
||||
PRN_CLEAR := 0x8BF00001
|
||||
PRN_FLUSH := 0x8BF00002
|
||||
#define PRN_CLEAR 0x8BF00001
|
||||
#define PRN_FLUSH 0x8BF00002
|
||||
|
||||
;
|
||||
; CRT librairies
|
||||
;
|
||||
|
||||
include "crt/sys.k"
|
||||
include "crt/str.k"
|
||||
include "crt/mem.k"
|
||||
include "crt/time.k"
|
||||
#include "crt/sys.k"
|
||||
#include "crt/str.k"
|
||||
#include "crt/mem.k"
|
||||
#include "crt/time.k"
|
||||
|
||||
include "crt/fmt/ltostr.k"
|
||||
include "crt/fmt/strtol.k"
|
||||
include "crt/fmt/doprnt.k"
|
||||
include "crt/fmt/printf.k"
|
||||
#include "crt/fmt/ltostr.k"
|
||||
#include "crt/fmt/strtol.k"
|
||||
#include "crt/fmt/doprnt.k"
|
||||
#include "crt/fmt/printf.k"
|
||||
|
||||
exit:
|
||||
mov rax, Sys.Exit
|
||||
|
33
ka/doskrnl.k
33
ka/doskrnl.k
@ -4,24 +4,23 @@
|
||||
__sysmain:
|
||||
jmp start
|
||||
|
||||
|
||||
include "crt/crt.k"
|
||||
#include "crt/crt.k"
|
||||
|
||||
;
|
||||
; Special addresses
|
||||
;
|
||||
DOSKRNL_CODE := 0x100000 ; 1MB
|
||||
DOSKRNL_STACK := 0x104000 ; + 16KB
|
||||
TRAP0_STACK := 0x104800 ; + 18KB
|
||||
INTR0_STACK := 0x105000 ; + 20KB
|
||||
EXCT0_STACK := 0x105800 ; + 22KB
|
||||
#define DOSKRNL_CODE 0x100000 ; 1MB
|
||||
#define DOSKRNL_STACK 0x104000 ; + 16KB
|
||||
#define TRAP0_STACK 0x104800 ; + 18KB
|
||||
#define INTR0_STACK 0x105000 ; + 20KB
|
||||
#define EXCT0_STACK 0x105800 ; + 22KB
|
||||
|
||||
; The kernel guarantees that COMMAND.COM
|
||||
; will always be loaded on a 16KB boundary
|
||||
; This is guaranteed to be the case in all
|
||||
; future versions as well
|
||||
CMDCOM_LOADP := 0x108000 ; + 32KB
|
||||
CMDCOM_MAXSZ := 0x80000 ; 512KB
|
||||
#define CMDCOM_LOADP 0x108000 ; + 32KB
|
||||
#define CMDCOM_MAXSZ 0x80000 ; 512KB
|
||||
|
||||
;
|
||||
; Entry point
|
||||
@ -40,14 +39,14 @@ start:
|
||||
; Disk Operating System
|
||||
;
|
||||
|
||||
include "sys/drv/cpudev.k"
|
||||
include "sys/drv/memdev.k"
|
||||
include "sys/drv/diskdev.k"
|
||||
#include "sys/drv/cpudev.k"
|
||||
#include "sys/drv/memdev.k"
|
||||
#include "sys/drv/diskdev.k"
|
||||
|
||||
include "sys/intr/excepts.k"
|
||||
include "sys/intr/common.k"
|
||||
include "sys/intr/trap0.k"
|
||||
#include "sys/intr/excepts.k"
|
||||
#include "sys/intr/common.k"
|
||||
#include "sys/intr/trap0.k"
|
||||
|
||||
include "sys/dumprf.k"
|
||||
include "sys/main.k"
|
||||
#include "sys/dumprf.k"
|
||||
#include "sys/main.k"
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
start:
|
||||
jmp main
|
||||
|
||||
include "crt/crt.k"
|
||||
#include "crt/crt.k"
|
||||
|
||||
main:
|
||||
mov rsp, 0x104000
|
||||
|
@ -158,5 +158,5 @@ N := 11
|
||||
.dirmsg = "Directory of C:\\\n\n"
|
||||
|
||||
.bytesstr = "%d kilobytes + %d bytes"
|
||||
# .bytesstr = "%dMB + %dKB + %dB" # too soon
|
||||
; .bytesstr = "%dMB + %dKB + %dB" # too soon
|
||||
|
||||
|
@ -54,3 +54,4 @@
|
||||
|
||||
; unreachable
|
||||
jmp abort
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
<escape-char>\</escape-char>
|
||||
|
||||
<line-comment _name="Line Comment" style="Comment">
|
||||
<start-regex>#|@|;|/</start-regex>
|
||||
<start-regex>@|;|/</start-regex>
|
||||
</line-comment>
|
||||
|
||||
<block-comment _name="Block Comment" style="Comment">
|
||||
@ -26,6 +26,10 @@
|
||||
<regex>[ ]*.[A-Za-z_0-9.]*\:</regex>
|
||||
</pattern-item>
|
||||
|
||||
<pattern-item _name="Preproc" style="Preprocessor">
|
||||
<regex>^\#(include|define|if|ifdef|else|endif|undef|pragma|error)</regex>
|
||||
</pattern-item>
|
||||
|
||||
<string _name="String" style = "String" end-at-line-end="TRUE">
|
||||
<start-regex>"</start-regex>
|
||||
<end-regex>"</end-regex>
|
||||
@ -37,10 +41,9 @@
|
||||
</string>
|
||||
|
||||
<keyword-list _name="Assembler Cmds" style="def:preprocessor"
|
||||
case-sensitive="TRUE"
|
||||
match-empty-string-at-beginning = "TRUE"
|
||||
match-empty-string-at-end = "TRUE">
|
||||
<keyword>include</keyword>
|
||||
<keyword>(include|define|if|ifdef|else|endif|undef|pragma|error)</keyword>
|
||||
</keyword-list>
|
||||
|
||||
<pattern-item _name="Instructions" style="def:keyword" case-sensitive="FALSE"
|
||||
|
Loading…
x
Reference in New Issue
Block a user