mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
vm
This commit is contained in:
parent
40653a8047
commit
ce8411be8e
47
as/regs.lst
47
as/regs.lst
@ -1,11 +1,11 @@
|
|||||||
rzx zero
|
rzx zero
|
||||||
fc1
|
|
||||||
cr0 c0
|
cr0 c0
|
||||||
cr1 c1
|
cr1 c1
|
||||||
cr2 c2
|
cr2 c2
|
||||||
cr3 c3
|
rfx fx
|
||||||
cr4 c4
|
rip ip
|
||||||
trp tp
|
rbp bp
|
||||||
|
rsp sp
|
||||||
|
|
||||||
rax ax r0
|
rax ax r0
|
||||||
rbx bx r1
|
rbx bx r1
|
||||||
@ -13,31 +13,22 @@ rcx cx r2
|
|||||||
rdx dx r3
|
rdx dx r3
|
||||||
rsi si r4
|
rsi si r4
|
||||||
rdi di r5
|
rdi di r5
|
||||||
rbp bp r6
|
ax0 a0 r6
|
||||||
rsp sp r7
|
ax1 a1 r7
|
||||||
rfx fs r8
|
ax2 a2 r8
|
||||||
rip ip r9
|
ax3 a3 r9
|
||||||
r10
|
ax4 a4 r10
|
||||||
r11
|
ax5 a5 r11
|
||||||
|
|
||||||
r12
|
r12
|
||||||
r13
|
r13
|
||||||
r14
|
r14
|
||||||
r15
|
r15
|
||||||
|
r16
|
||||||
ax0 a0 r16
|
r17
|
||||||
ax1 a1 r17
|
r18
|
||||||
ax2 a2 r18
|
r19
|
||||||
ax3 a3 r19
|
r20
|
||||||
ax4 a4 r20
|
grp gp
|
||||||
ax5 a5 r21
|
trp tp
|
||||||
ax6 a6 r22
|
srp sp
|
||||||
ax7 a7 r23
|
|
||||||
|
|
||||||
nx0 n0 r24
|
|
||||||
nx1 n1 r25
|
|
||||||
nx2 n2 r26
|
|
||||||
nx3 n3 r27
|
|
||||||
nx4 n4 r28
|
|
||||||
nx5 n5 r29
|
|
||||||
nx6 n6 r30
|
|
||||||
nx7 n7 r31
|
|
||||||
|
21
ka/ABI
21
ka/ABI
@ -71,22 +71,21 @@ Aside from the DF flag, a function cannot assume anything about the state
|
|||||||
of the flags in the FLG register.
|
of the flags in the FLG register.
|
||||||
|
|
||||||
Passing parameters is done using the following registers, in that order:
|
Passing parameters is done using the following registers, in that order:
|
||||||
a0-a7
|
ax0, ax1, ax2, ax3, ax4, ax5
|
||||||
|
|
||||||
The stack is never used for argument passing, except for variadic functions,
|
Further parameters are passed on the stack in reverse order. The caller then
|
||||||
cf the next section. If you need to pass large structures of data, pass
|
cleans the stack.
|
||||||
their address in an appropriate register.
|
|
||||||
|
|
||||||
Return values are passed in 'rax'. If the return value does not fit
|
Return values are passed in 'rax'. If the return value does not fit
|
||||||
and require more registers, use the following registers, in that order:
|
and require more registers, use the following registers, in that order:
|
||||||
rax, rdx
|
rax, rdx
|
||||||
|
|
||||||
The following registers are volatile; the calling function cannot assume
|
The following registers are volatile; the caller cannot assume
|
||||||
that they will be left unmodified by the called function:
|
that they will be left unmodified by the callee:
|
||||||
rax, rcx, rdx, r8-r15, a0-a7
|
rax, rbx, rcx, rdx, rsi, rdi, ax0, ax1, ax2, ax3, ax4, ax5
|
||||||
|
|
||||||
The following registers are nonvolatile; the called function must preserve them:
|
The following registers are nonvolatile; the callee must preserve them:
|
||||||
rbx, rsi, rdi, n0-n7, rbp, rsp
|
r12, r13, r14, r15, r16, r17, r18, r19, r20
|
||||||
|
|
||||||
#------------------------------------------------------------------------------#
|
#------------------------------------------------------------------------------#
|
||||||
|
|
||||||
@ -119,10 +118,6 @@ variadic function's rbp+16
|
|||||||
|
|
||||||
4. SPECIAL REGISTERS
|
4. SPECIAL REGISTERS
|
||||||
|
|
||||||
The 'inv' register cannot be referenced by machine code except when specified
|
|
||||||
as an offset register in the [reg+reg(*/+...)] memory formats; in these case,
|
|
||||||
'inv' can be assumed to be always null.
|
|
||||||
|
|
||||||
(TO BE COMPLETED)
|
(TO BE COMPLETED)
|
||||||
|
|
||||||
#------------------------------------------------------------------------------#
|
#------------------------------------------------------------------------------#
|
||||||
|
@ -6,45 +6,46 @@
|
|||||||
; int doprnt(PUTC putc, int n, const char *fmt, va_list ap)
|
; int doprnt(PUTC putc, int n, const char *fmt, va_list ap)
|
||||||
;
|
;
|
||||||
doprnt:
|
doprnt:
|
||||||
enter 8
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
mov q[rbp-8], rbx
|
push r12
|
||||||
mov q[rbp-16], nx0
|
push r13
|
||||||
mov q[rbp-24], nx1
|
push r14
|
||||||
mov q[rbp-32], rdi
|
push r15
|
||||||
mov q[rbp-40], rsi
|
push r16
|
||||||
mov q[rbp-48], nx3
|
push r17
|
||||||
|
|
||||||
mov rbx, ax2 ; fmt
|
mov r12, ax2 ; fmt
|
||||||
mov nx3, ax0 ; putc
|
mov r14, ax3 ; va_list
|
||||||
mov nx0, ax1 ; n
|
mov r15, ax1 ; n
|
||||||
mov rsi, ax3 ; va_list
|
mov r16, zero ; return value
|
||||||
mov nx1, zero ; return value
|
mov r17, ax0 ; putc
|
||||||
|
|
||||||
.main_loop:
|
.main_loop:
|
||||||
; find '%' or null-terminator
|
; find '%' or null-terminator
|
||||||
mov rcx, STRLEN_MAX
|
mov rcx, STRLEN_MAX
|
||||||
mov rdi, rbx
|
mov r13, r12
|
||||||
scasb.rep.nz rdi, '%'
|
scasb.rep.nz r13, '%'
|
||||||
|
|
||||||
; everything below rdi is a regular character; print it
|
; everything below r13 is a regular character; print it
|
||||||
.print_regular:
|
.print_regular:
|
||||||
b.z rbx, rdi, .check_modf
|
b.z r12, r13, .check_modf
|
||||||
|
|
||||||
mov ax0, b[rbx]
|
mov ax0, b[r12]
|
||||||
call .doput
|
call .doput
|
||||||
|
|
||||||
add rbx, rbx, 1
|
add r12, r12, 1
|
||||||
jmp .print_regular
|
jmp .print_regular
|
||||||
|
|
||||||
.check_modf:
|
.check_modf:
|
||||||
; did we find a '%' ?
|
; did we find a '%' ?
|
||||||
; if not, then we found fmt's null-terminator; we're done
|
; if not, then we found fmt's null-terminator; we're done
|
||||||
b.nz b[rbx], '%', .epilogue
|
b.nz b[r12], '%', .epilogue
|
||||||
|
|
||||||
; we did find a modifier / '%'
|
; we did find a modifier / '%'
|
||||||
mov rax, b[rbx+1]
|
mov rax, b[r12+1]
|
||||||
add rbx, rbx, 2
|
add r12, r12, 2
|
||||||
|
|
||||||
b.z rax, 's', .modf_s
|
b.z rax, 's', .modf_s
|
||||||
b.z rax, 'c', .modf_c
|
b.z rax, 'c', .modf_c
|
||||||
@ -60,24 +61,24 @@ doprnt:
|
|||||||
|
|
||||||
.modf_s:
|
.modf_s:
|
||||||
; get string address
|
; get string address
|
||||||
mov rdi, q[rsi]
|
mov r13, q[r14]
|
||||||
add rsi, rsi, 8
|
add r14, r14, 8
|
||||||
|
|
||||||
cmp rdi, zero
|
cmp r13, zero
|
||||||
jmp.z .nullstring
|
jmp.z .nullstring
|
||||||
|
|
||||||
.print_string:
|
.print_string:
|
||||||
mov ax0, b[rdi]
|
mov ax0, b[r13]
|
||||||
cmp ax0, zero
|
cmp ax0, zero
|
||||||
jmp.z .main_loop
|
jmp.z .main_loop
|
||||||
|
|
||||||
add rdi, rdi, 1
|
add r13, r13, 1
|
||||||
call .doput
|
call .doput
|
||||||
jmp .print_string
|
jmp .print_string
|
||||||
|
|
||||||
.modf_c:
|
.modf_c:
|
||||||
mov ax0, q[rsi]
|
mov ax0, q[r14]
|
||||||
add rsi, rsi, 8
|
add r14, r14, 8
|
||||||
call .doput
|
call .doput
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
@ -105,22 +106,22 @@ doprnt:
|
|||||||
.print_number:
|
.print_number:
|
||||||
; allocate itoa conversion buffer
|
; allocate itoa conversion buffer
|
||||||
sub rsp, rsp, 80
|
sub rsp, rsp, 80
|
||||||
mov rdi, rsp
|
mov r13, rsp
|
||||||
|
|
||||||
; assume modifier already set up ax2
|
; assume modifier already set up ax2
|
||||||
mov ax0, rsp
|
mov ax0, rsp
|
||||||
mov ax1, q[rsi]
|
mov ax1, q[r14]
|
||||||
call itoa
|
call itoa
|
||||||
add rsi, rsi, 8
|
add r14, r14, 8
|
||||||
|
|
||||||
.print_itoa_buf:
|
.print_itoa_buf:
|
||||||
mov ax0, b[rdi]
|
mov ax0, b[r13]
|
||||||
|
|
||||||
cmp ax0, zero
|
cmp ax0, zero
|
||||||
add.z rsp, rsp, 80
|
add.z rsp, rsp, 80
|
||||||
jmp.z .main_loop
|
jmp.z .main_loop
|
||||||
|
|
||||||
add rdi, rdi, 1
|
add r13, r13, 1
|
||||||
call .doput
|
call .doput
|
||||||
jmp .print_itoa_buf
|
jmp .print_itoa_buf
|
||||||
|
|
||||||
@ -147,13 +148,15 @@ doprnt:
|
|||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
.epilogue:
|
.epilogue:
|
||||||
mov rax, nx1
|
mov rax, r16
|
||||||
mov rbx, q[rbp-8]
|
|
||||||
mov nx0, q[rbp-16]
|
pop r17
|
||||||
mov nx1, q[rbp-24]
|
pop r16
|
||||||
mov rdi, q[rbp-32]
|
pop r15
|
||||||
mov rsi, q[rbp-40]
|
pop r14
|
||||||
mov nx3, q[rbp-48]
|
pop r13
|
||||||
|
pop r12
|
||||||
|
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
;
|
;
|
||||||
@ -161,22 +164,22 @@ doprnt:
|
|||||||
;
|
;
|
||||||
.doput:
|
.doput:
|
||||||
; update print count
|
; update print count
|
||||||
add nx1, nx1, 1
|
add r16, r16, 1
|
||||||
|
|
||||||
; if n==0, don't print
|
; if n==0, don't print
|
||||||
; we follow the C convention that sprintf()-like functions
|
; we follow the C convention that sprintf()-like functions
|
||||||
; should return the number of characters that would have
|
; should return the number of characters that would have
|
||||||
; been printed/written if 'n' were big enough
|
; been printed/written if 'n' were big enough
|
||||||
cmp nx0, zero
|
cmp r15, zero
|
||||||
ret.z
|
ret.z
|
||||||
|
|
||||||
; if n>0, decrement n and print
|
; if n>0, decrement n and print
|
||||||
sub nx0, nx0, 1
|
sub r15, r15, 1
|
||||||
call nx3
|
call r17
|
||||||
|
|
||||||
; did putc fail?
|
; did putc fail?
|
||||||
cmp rax, zero
|
cmp rax, zero
|
||||||
mov.nz nx0, zero ; yes, so artificially set n=0
|
mov.nz r15, zero ; yes, so artificially set n=0
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ utoa:
|
|||||||
;
|
;
|
||||||
ltostr:
|
ltostr:
|
||||||
mov rax, ax0
|
mov rax, ax0
|
||||||
mov r11, zero
|
mov rcx, zero
|
||||||
|
|
||||||
; make sure base is in [2, 32]
|
; make sure base is in [2, 32]
|
||||||
b.b ax2, 2, .bad
|
b.b ax2, 2, .bad
|
||||||
@ -34,26 +34,26 @@ ltostr:
|
|||||||
b.z ax3, zero, .conv
|
b.z ax3, zero, .conv
|
||||||
b.nz ax2, 10, .conv ; base 10
|
b.nz ax2, 10, .conv ; base 10
|
||||||
|
|
||||||
shr r11, ax1, 63 ; extract ax1 sign
|
shr rcx, ax1, 63 ; extract ax1 sign
|
||||||
cmp r11, zero ; negative?
|
cmp rcx, zero ; negative?
|
||||||
sub.nz ax1, zero, ax1 ; yes
|
sub.nz ax1, zero, ax1 ; yes
|
||||||
|
|
||||||
; main loop
|
; main loop
|
||||||
.conv:
|
.conv:
|
||||||
b.z ax1, zero, .fini
|
b.z ax1, zero, .fini
|
||||||
|
|
||||||
rem r10, ax1, ax2 ; ax1 % base
|
rem rdx, ax1, ax2 ; ax1 % base
|
||||||
|
|
||||||
b.a r10, 9, .nondec ; r10 > 9 ?
|
b.a rdx, 9, .nondec ; rdx > 9 ?
|
||||||
|
|
||||||
add r10, r10, '0'
|
add rdx, rdx, '0'
|
||||||
jmp .next
|
jmp .next
|
||||||
|
|
||||||
.nondec:
|
.nondec:
|
||||||
add r10, r10, 55 ; 'A' - 10
|
add rdx, rdx, 55 ; 'A' - 10
|
||||||
|
|
||||||
.next:
|
.next:
|
||||||
mov b[ax0], r10
|
mov b[ax0], rdx
|
||||||
add ax0, ax0, 1
|
add ax0, ax0, 1
|
||||||
|
|
||||||
div ax1, ax1, ax2
|
div ax1, ax1, ax2
|
||||||
@ -61,7 +61,7 @@ ltostr:
|
|||||||
|
|
||||||
; add minus flag, null-terminate and reverse
|
; add minus flag, null-terminate and reverse
|
||||||
.fini:
|
.fini:
|
||||||
cmp r11, -1
|
cmp rcx, -1
|
||||||
mov.z b[ax0], '-'
|
mov.z b[ax0], '-'
|
||||||
add.z ax0, ax0, 1
|
add.z ax0, ax0, 1
|
||||||
|
|
||||||
|
@ -48,14 +48,14 @@ strtoq:
|
|||||||
|
|
||||||
; signed?
|
; signed?
|
||||||
cmp ax2, zero
|
cmp ax2, zero
|
||||||
mov.z r10, zero
|
mov.z rsi, zero
|
||||||
jmp.z .unsigned
|
jmp.z .unsigned
|
||||||
|
|
||||||
; parse '-'
|
; parse '-'
|
||||||
cmp b[rdx], '-'
|
cmp b[rdx], '-'
|
||||||
add.z rdx, rdx, 1
|
add.z rdx, rdx, 1
|
||||||
mov.z r10, 1
|
mov.z rsi, 1
|
||||||
mov.nz r10, zero
|
mov.nz rsi, zero
|
||||||
|
|
||||||
.unsigned:
|
.unsigned:
|
||||||
; base 0
|
; base 0
|
||||||
@ -113,37 +113,37 @@ strtoq:
|
|||||||
mov ax1, 8
|
mov ax1, 8
|
||||||
|
|
||||||
.main_loop:
|
.main_loop:
|
||||||
movzx r12, b[rdx]
|
movzx rcx, b[rdx]
|
||||||
add rdx, rdx, 1
|
add rdx, rdx, 1
|
||||||
|
|
||||||
cmp r12, '0'
|
cmp rcx, '0'
|
||||||
jmp.b .done
|
jmp.b .done
|
||||||
cmp.ae r12, '9'
|
cmp.ae rcx, '9'
|
||||||
sub.be r12, r12, '0'
|
sub.be rcx, rcx, '0'
|
||||||
jmp.be .next
|
jmp.be .next
|
||||||
|
|
||||||
cmp r12, 'A'
|
cmp rcx, 'A'
|
||||||
cmp.ae r12, 'Z'
|
cmp.ae rcx, 'Z'
|
||||||
sub.be r12, r12, 55 ; 'A' - 10
|
sub.be rcx, rcx, 55 ; 'A' - 10
|
||||||
jmp.be .next
|
jmp.be .next
|
||||||
|
|
||||||
cmp r12, 'a'
|
cmp rcx, 'a'
|
||||||
jmp.b .next
|
jmp.b .next
|
||||||
cmp.ae r12, 'z'
|
cmp.ae rcx, 'z'
|
||||||
sub.be r12, r12, 87 ; 'a' - 10
|
sub.be rcx, rcx, 87 ; 'a' - 10
|
||||||
jmp.be .next
|
jmp.be .next
|
||||||
|
|
||||||
.next:
|
.next:
|
||||||
; too large for base?
|
; too large for base?
|
||||||
b.ae r12, ax1, .done
|
b.ae rcx, ax1, .done
|
||||||
|
|
||||||
mul rax, rax, ax1
|
mul rax, rax, ax1
|
||||||
add rax, rax, r12
|
add rax, rax, rcx
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
; negative?
|
; negative?
|
||||||
cmp r10, zero
|
cmp rsi, zero
|
||||||
ret.z
|
ret.z
|
||||||
|
|
||||||
; yes
|
; yes
|
||||||
|
@ -45,32 +45,32 @@ DaysInYear:
|
|||||||
; TIME *GetTimeUTC(void)
|
; TIME *GetTimeUTC(void)
|
||||||
;
|
;
|
||||||
GetTimeUTC:
|
GetTimeUTC:
|
||||||
ytime r11, r12, r13
|
ytime ax0, ax1, ax2
|
||||||
mov rdx, .buf
|
mov rdx, .buf
|
||||||
|
|
||||||
; seconds
|
; seconds
|
||||||
rem rcx, r11, 60
|
rem rcx, ax0, 60
|
||||||
mov b[rdx], rcx
|
mov b[rdx], rcx
|
||||||
|
|
||||||
; minutes
|
; minutes
|
||||||
div rcx, r11, 60
|
div rcx, ax0, 60
|
||||||
rem rcx, rcx, 60
|
rem rcx, rcx, 60
|
||||||
mov b[rdx+1], rcx
|
mov b[rdx+1], rcx
|
||||||
|
|
||||||
; hours
|
; hours
|
||||||
div rcx, r11, 3600
|
div rcx, ax0, 3600
|
||||||
rem rcx, rcx, 24
|
rem rcx, rcx, 24
|
||||||
mov b[rdx+2], rcx
|
mov b[rdx+2], rcx
|
||||||
|
|
||||||
; month days
|
; month days
|
||||||
div rcx, r11, 3600*24
|
div rcx, ax0, 3600*24
|
||||||
mov b[rdx+3], rcx
|
mov b[rdx+3], rcx
|
||||||
|
|
||||||
; month
|
; month
|
||||||
mov b[rdx+4], r12
|
mov b[rdx+4], ax1
|
||||||
|
|
||||||
; years
|
; years
|
||||||
mov w[rdx+6], r13
|
mov w[rdx+6], ax2
|
||||||
|
|
||||||
;
|
;
|
||||||
; ydays (TODO)
|
; ydays (TODO)
|
||||||
|
@ -22,8 +22,8 @@ strcmp:
|
|||||||
jmp.nz .2
|
jmp.nz .2
|
||||||
|
|
||||||
; both zero?
|
; both zero?
|
||||||
add r11, rax, rdx
|
add rbx, rax, rdx
|
||||||
b.z r11, zero, .2
|
b.z rbx, zero, .2
|
||||||
|
|
||||||
add ax0, ax0, 1
|
add ax0, ax0, 1
|
||||||
add ax1, ax1, 1
|
add ax1, ax1, 1
|
||||||
|
@ -12,7 +12,7 @@ strrev:
|
|||||||
ret.z
|
ret.z
|
||||||
|
|
||||||
; save str's location
|
; save str's location
|
||||||
mov r10, ax1
|
mov rsi, ax1
|
||||||
|
|
||||||
; go to str's end, just before
|
; go to str's end, just before
|
||||||
; the null terminator
|
; the null terminator
|
||||||
@ -26,7 +26,7 @@ strrev:
|
|||||||
mov rax, b[ax1]
|
mov rax, b[ax1]
|
||||||
mov b[ax0], rax
|
mov b[ax0], rax
|
||||||
|
|
||||||
cmp ax1, r10
|
cmp ax1, rsi
|
||||||
mov.z b[ax0+1], zero
|
mov.z b[ax0+1], zero
|
||||||
ret.z
|
ret.z
|
||||||
|
|
||||||
|
@ -4,37 +4,34 @@
|
|||||||
TrapHandlers.prolog:
|
TrapHandlers.prolog:
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
sub rsp, rsp, 24
|
sub rsp, rsp, 24
|
||||||
mov q[rbp-8], r11
|
mov q[rbp-8], r13
|
||||||
mov q[rbp-16], r12
|
mov q[rbp-16], r14
|
||||||
mov q[rbp-24], r13
|
mov q[rbp-24], r15
|
||||||
|
|
||||||
mov rdx, cr2
|
|
||||||
|
|
||||||
; nx0 = caller's cr2
|
; nx0 = caller's cr2
|
||||||
mov ax0, r12
|
mov ax0, r14
|
||||||
mov ax1, $cr2
|
mov ax1, $cr2
|
||||||
iocall CPUDEV, RFS.LoadReg.slot
|
call RFS.LoadReg
|
||||||
|
|
||||||
mov nx0, cr2
|
mov r12, rax
|
||||||
mov cr2, rdx
|
|
||||||
mov rdx, zero
|
mov rdx, zero
|
||||||
|
|
||||||
jmp rcx
|
jmp rcx
|
||||||
|
|
||||||
TrapHandlers.epilog:
|
TrapHandlers.epilog:
|
||||||
mov r13, q[rbp-24]
|
mov r15, q[rbp-24]
|
||||||
mov r12, q[rbp-16]
|
mov r14, q[rbp-16]
|
||||||
mov r11, q[rbp-8]
|
mov r13, q[rbp-8]
|
||||||
|
|
||||||
; TRAP return values: RAX-RDX
|
; TRAP return values: RAX-RDX
|
||||||
|
|
||||||
mov ax2, rax
|
mov ax2, rax
|
||||||
call RFS.StoreReg, r12, $rax
|
call RFS.StoreReg, r14, $rax
|
||||||
|
|
||||||
mov ax2, rdx
|
mov ax2, rdx
|
||||||
call RFS.StoreReg, r12, $rdx
|
call RFS.StoreReg, r14, $rdx
|
||||||
|
|
||||||
call IDT.DoneHandling, r11
|
call IDT.DoneHandling, r13
|
||||||
|
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ trap0_handler:
|
|||||||
jmp TrapHandlers.prolog
|
jmp TrapHandlers.prolog
|
||||||
|
|
||||||
.text:
|
.text:
|
||||||
mov ax0, r12
|
mov ax0, r14
|
||||||
mov ax1, $rax
|
mov ax1, $rax
|
||||||
call RFS.LoadReg
|
call RFS.LoadReg
|
||||||
call RFS.LoadArgs
|
call RFS.LoadArgs
|
||||||
@ -87,17 +87,17 @@ trap0_handler:
|
|||||||
; Disk API
|
; Disk API
|
||||||
;
|
;
|
||||||
.handle_FindFirst:
|
.handle_FindFirst:
|
||||||
add ax0, ax0, nx0
|
add ax0, ax0, r12
|
||||||
call DISK.FindFirst
|
call DISK.FindFirst
|
||||||
jmp .fini
|
jmp .fini
|
||||||
|
|
||||||
.handle_FindNext:
|
.handle_FindNext:
|
||||||
add ax0, ax0, nx0
|
add ax0, ax0, r12
|
||||||
call DISK.FindNext
|
call DISK.FindNext
|
||||||
jmp .fini
|
jmp .fini
|
||||||
|
|
||||||
.handle_OpenFile:
|
.handle_OpenFile:
|
||||||
add ax0, ax0, nx0
|
add ax0, ax0, r12
|
||||||
call DISK.OpenFile
|
call DISK.OpenFile
|
||||||
jmp .fini
|
jmp .fini
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ trap0_handler:
|
|||||||
jmp .fini
|
jmp .fini
|
||||||
|
|
||||||
.handle_ReadFile:
|
.handle_ReadFile:
|
||||||
add ax1, ax1, nx0
|
add ax1, ax1, r12
|
||||||
call DISK.ReadFile
|
call DISK.ReadFile
|
||||||
jmp .fini
|
jmp .fini
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ trap0_handler:
|
|||||||
; Misc.
|
; Misc.
|
||||||
;
|
;
|
||||||
.handle_Shutdown:
|
.handle_Shutdown:
|
||||||
mov nx0, zero
|
mov r12, zero
|
||||||
stop
|
stop
|
||||||
|
|
||||||
.handle_HaltMode:
|
.handle_HaltMode:
|
||||||
|
@ -4,9 +4,12 @@
|
|||||||
NAME_MAX := 256
|
NAME_MAX := 256
|
||||||
|
|
||||||
builtins.dir:
|
builtins.dir:
|
||||||
push nx0
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
mov nx0, zero # no. of files found
|
push r12
|
||||||
|
|
||||||
|
mov r12, zero # no. of files found
|
||||||
|
|
||||||
mov rcx, STRLEN_MAX
|
mov rcx, STRLEN_MAX
|
||||||
mov rdx, .dirmsg
|
mov rdx, .dirmsg
|
||||||
@ -32,27 +35,27 @@ builtins.dir:
|
|||||||
b.z rax, 0, .end
|
b.z rax, 0, .end
|
||||||
|
|
||||||
; found something
|
; found something
|
||||||
add nx0, nx0, 1
|
add r12, r12, 1
|
||||||
|
|
||||||
; separate extension from file name
|
; separate extension from file name
|
||||||
mov rcx, NAME_MAX
|
mov rcx, NAME_MAX
|
||||||
mov r10, .buf
|
mov rsi, .buf
|
||||||
mov r11, r10
|
mov rdi, rsi
|
||||||
scasb.rep.nz r10, '.'
|
scasb.rep.nz rsi, '.'
|
||||||
|
|
||||||
; print file name
|
; print file name
|
||||||
sub rcx, r10, r11
|
sub rcx, rsi, rdi
|
||||||
prns.rep r11
|
prns.rep rdi
|
||||||
|
|
||||||
; calculate where to put extension
|
; calculate where to put extension
|
||||||
sub r11, r10, .buf
|
sub rdi, rsi, .buf
|
||||||
sub r11, r11, 1
|
sub rdi, rdi, 1
|
||||||
|
|
||||||
.ext_pad:
|
.ext_pad:
|
||||||
; print at least 11 non-space characters before extension
|
; print at least 11 non-space characters before extension
|
||||||
b.ae r11, 11, .print_ext
|
b.ae rdi, 11, .print_ext
|
||||||
prn ' '
|
prn ' '
|
||||||
add r11, r11, 1
|
add rdi, rdi, 1
|
||||||
jmp .ext_pad
|
jmp .ext_pad
|
||||||
|
|
||||||
.print_ext:
|
.print_ext:
|
||||||
@ -60,16 +63,16 @@ builtins.dir:
|
|||||||
mov rcx, 4
|
mov rcx, 4
|
||||||
prn ' '
|
prn ' '
|
||||||
|
|
||||||
cmp b[r10], '.'
|
cmp b[rsi], '.'
|
||||||
add.z r10, r10, 1
|
add.z rsi, rsi, 1
|
||||||
|
|
||||||
.print_ext.1:
|
.print_ext.1:
|
||||||
b.z b[r10], 0, .print_ext.2
|
b.z b[rsi], 0, .print_ext.2
|
||||||
|
|
||||||
; print and decrease rcx, unless it's already 0
|
; print and decrease rcx, unless it's already 0
|
||||||
mov r12, b[r10]
|
mov rbx, b[rsi]
|
||||||
prn r12
|
prn rbx
|
||||||
add r10, r10, 1
|
add rsi, rsi, 1
|
||||||
sub.cxnz rcx, rcx, 1
|
sub.cxnz rcx, rcx, 1
|
||||||
|
|
||||||
jmp .print_ext.1
|
jmp .print_ext.1
|
||||||
@ -102,13 +105,15 @@ builtins.dir:
|
|||||||
jmp .next
|
jmp .next
|
||||||
|
|
||||||
.end:
|
.end:
|
||||||
push nx0
|
push r12
|
||||||
call printf, .endstr1
|
call printf, .endstr1
|
||||||
add rsp, rsp, 8
|
add rsp, rsp, 8
|
||||||
|
|
||||||
call print, .endstr2
|
call print, .endstr2
|
||||||
|
|
||||||
pop nx0
|
pop r12
|
||||||
|
|
||||||
|
leave
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.buf = [256]
|
.buf = [256]
|
||||||
|
@ -79,20 +79,20 @@ main:
|
|||||||
scasb.rep.nz rdx, ' '
|
scasb.rep.nz rdx, ' '
|
||||||
|
|
||||||
; argv1 exists? if so, save its position
|
; argv1 exists? if so, save its position
|
||||||
mov r11, rdx
|
mov rsi, rdx
|
||||||
b.z b[r11], zero, .no_argv1
|
b.z b[rsi], zero, .no_argv1
|
||||||
add r11, r11, 1
|
add rsi, rsi, 1
|
||||||
|
|
||||||
.next_space:
|
.next_space:
|
||||||
mov r10, b[r11]
|
mov rcx, b[rsi]
|
||||||
b.z r10, zero, .no_argv1
|
b.z rdx, zero, .no_argv1
|
||||||
|
|
||||||
; skip spaces
|
; skip spaces
|
||||||
cmp r10, ' '
|
cmp rdx, ' '
|
||||||
add.z r11, r11, 1
|
add.z rsi, rsi, 1
|
||||||
jmp.z .next_space
|
jmp.z .next_space
|
||||||
|
|
||||||
mov q[argv1pos], r11
|
mov q[argv1pos], rsi
|
||||||
|
|
||||||
; fallthrough
|
; fallthrough
|
||||||
|
|
||||||
@ -110,8 +110,8 @@ main:
|
|||||||
.mmove:
|
.mmove:
|
||||||
jmp.cxz .detect_builtin
|
jmp.cxz .detect_builtin
|
||||||
|
|
||||||
mov r11, b[rdx]
|
mov rsi, b[rdx]
|
||||||
mov b[rax], r11
|
mov b[rax], rsi
|
||||||
|
|
||||||
add rdx, rdx, 1
|
add rdx, rdx, 1
|
||||||
add rax, rax, 1
|
add rax, rax, 1
|
||||||
|
16
vm/dv/CPUDEV
16
vm/dv/CPUDEV
@ -16,7 +16,7 @@ CPU device function slots:
|
|||||||
24 i i - y moveframe move frame #ax1 to (inactive) frame index #ax0
|
24 i i - y moveframe move frame #ax1 to (inactive) frame index #ax0
|
||||||
25 i - - - switchrf switch to register frame #ax0
|
25 i - - - switchrf switch to register frame #ax0
|
||||||
26-31 - - - - (reserved) (reserved)
|
26-31 - - - - (reserved) (reserved)
|
||||||
32 i - - - loadargs load registers ax0-ax7 from frame #ax0
|
32 i - - - loadargs load registers ax0-ax5 from frame #ax0
|
||||||
33 i r - - loadreg rax = register #ax1 from frame #ax0
|
33 i r - - loadreg rax = register #ax1 from frame #ax0
|
||||||
34-47 - - - - (reserved) (reserved)
|
34-47 - - - - (reserved) (reserved)
|
||||||
48 i r i y storereg store ax2 into register #ax1 from frame #ax0
|
48 i r i y storereg store ax2 into register #ax1 from frame #ax0
|
||||||
@ -57,15 +57,15 @@ a certain E/I. If that same E/I happens again before that, the following happens
|
|||||||
- if this E/I is #DBF (double fault), the system crashes ("triple fault")
|
- if this E/I is #DBF (double fault), the system crashes ("triple fault")
|
||||||
- if this E/I is a hardware interrupt, it is queued (*** XXX ***)
|
- if this E/I is a hardware interrupt, it is queued (*** XXX ***)
|
||||||
|
|
||||||
When called, a handler will receive the number of the E/I it is handling in R10,
|
When called, a handler will receive the number of the E/I it is handling in R12,
|
||||||
and its own RFRAME ID in R11. (in particular, if exception #25 happens and there are no
|
and its own RFRAME ID in R13. (in particular, if exception #25 happens and there are no
|
||||||
handler for it, the handler #0 that will be called will receive '25' in R10, and '0' in R11).
|
handler for it, the handler #0 that will be called will receive '25' in R12, and '0' in R13).
|
||||||
R11 is the value that must be passed to the 'initdone' iocall.
|
R13 is the value that must be passed to the 'initdone' iocall.
|
||||||
The handler will also receive the previous RFRAME ID in R12.
|
The handler will also receive the previous RFRAME ID in R14.
|
||||||
R13 is also modified but its value is meaningful only to the processor.
|
R15 is also modified but its value is meaningful only to the processor.
|
||||||
|
|
||||||
To return from an E/I, *after* having called 'idtdone' (using the value originally in R11),
|
To return from an E/I, *after* having called 'idtdone' (using the value originally in R11),
|
||||||
the handler must simply restore R12's and R13's values to what they were when the handler
|
the handler must simply restore R14's and R15's values to what they were when the handler
|
||||||
started executing, and then use the 'IRET' instruction.
|
started executing, and then use the 'IRET' instruction.
|
||||||
|
|
||||||
Clearing the interrupt flag prevents (and queues) maskable hardware interrupts
|
Clearing the interrupt flag prevents (and queues) maskable hardware interrupts
|
||||||
|
@ -146,7 +146,6 @@ long cpudev_switchframe(ctx_t *ctx, dev_t *dev)
|
|||||||
|
|
||||||
rfs_current_idx = ax0;
|
rfs_current_idx = ax0;
|
||||||
ctx->rf = rfs[ax0];
|
ctx->rf = rfs[ax0];
|
||||||
fc2 = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -157,8 +156,6 @@ long cpudev_loadargs(ctx_t *ctx, dev_t *dev)
|
|||||||
{
|
{
|
||||||
CHK_FRAME(ax0);
|
CHK_FRAME(ax0);
|
||||||
|
|
||||||
R(AX7) = rfs[ax0][AX7];
|
|
||||||
R(AX6) = rfs[ax0][AX6];
|
|
||||||
R(AX5) = rfs[ax0][AX5];
|
R(AX5) = rfs[ax0][AX5];
|
||||||
R(AX4) = rfs[ax0][AX4];
|
R(AX4) = rfs[ax0][AX4];
|
||||||
R(AX3) = rfs[ax0][AX3];
|
R(AX3) = rfs[ax0][AX3];
|
||||||
@ -177,7 +174,7 @@ long cpudev_loadreg(ctx_t *ctx, dev_t *dev)
|
|||||||
_except(ctx, E_UDF,
|
_except(ctx, E_UDF,
|
||||||
"cpudev: register invalid or index out of range: #%u", ax1);
|
"cpudev: register invalid or index out of range: #%u", ax1);
|
||||||
|
|
||||||
R(ax1) = rfs[ax0][ax1];
|
R(RAX) = rfs[ax0][ax1];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,8 @@ IMPL_OUT;
|
|||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_0(cls) {
|
IMPL_START_0(cls) {
|
||||||
R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
|
R(RFX) = 0;
|
||||||
for (int i = R10; i <= NX7; i++) R(i) = 0;
|
for (int i = RAX; i <= R20; i++) R(i) = 0;
|
||||||
} IMPL_END;
|
} IMPL_END;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
@ -45,12 +45,12 @@ IMPL_START_1(trap) {
|
|||||||
|
|
||||||
IMPL_START_0(iret) {
|
IMPL_START_0(iret) {
|
||||||
if (ctx->dumpsw)
|
if (ctx->dumpsw)
|
||||||
trace("\nReturning from exception #%ld\n\n", R(R11));
|
trace("\nReturning from exception #%ld\n\n", R(R13));
|
||||||
|
|
||||||
// should do more checks
|
// should do more checks
|
||||||
R(RIP) = R(R13);
|
R(RIP) = R(R15);
|
||||||
rfs_current_idx = R(R12);
|
rfs_current_idx = R(R14);
|
||||||
ctx->rf = rfs[R(R12)];
|
ctx->rf = rfs[R(R14)];
|
||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
|
@ -89,11 +89,10 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
|||||||
ctx->rf = rfs[handler];
|
ctx->rf = rfs[handler];
|
||||||
rfs_current_idx = handler;
|
rfs_current_idx = handler;
|
||||||
|
|
||||||
fc2 = 0;
|
R(R12) = code;
|
||||||
R(R10) = code;
|
R(R13) = effcode;
|
||||||
R(R11) = effcode;
|
R(R14) = orig_frame;
|
||||||
R(R12) = orig_frame;
|
R(R15) = R(RIP);
|
||||||
R(R13) = R(RIP);
|
|
||||||
|
|
||||||
idt_handling[effcode]++;
|
idt_handling[effcode]++;
|
||||||
|
|
||||||
|
@ -70,10 +70,6 @@ void exec_instr(ctx_t *ctx,
|
|||||||
// Global instruction counter
|
// Global instruction counter
|
||||||
fc0++;
|
fc0++;
|
||||||
|
|
||||||
// Current frame instruction counter
|
|
||||||
fc2++; // since last frame change
|
|
||||||
fc1++; // since startup
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// For REPs we evaluate the condition AFTER running the instruction,
|
// For REPs we evaluate the condition AFTER running the instruction,
|
||||||
// in a do ... while(cond) fashion
|
// in a do ... while(cond) fashion
|
||||||
@ -112,9 +108,6 @@ do_rep:
|
|||||||
|
|
||||||
// Should we really count REP's in instruction count?
|
// Should we really count REP's in instruction count?
|
||||||
fc0++;
|
fc0++;
|
||||||
fc1++;
|
|
||||||
fc2++;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Show that we're REP'ing
|
// Show that we're REP'ing
|
||||||
if (ctx->dumpsw)
|
if (ctx->dumpsw)
|
||||||
|
32
vm/pc/regs.c
32
vm/pc/regs.c
@ -5,18 +5,16 @@
|
|||||||
|
|
||||||
reg_t arch_r[] =
|
reg_t arch_r[] =
|
||||||
{
|
{
|
||||||
{ "zero", GPR }, { "fc1", RES }, { "cr0", SYS }, { "cr1", SYS },
|
{ "zero", GPR }, { "cr0", SYS }, { "cr1", SYS }, { "cr2", SYS },
|
||||||
{ "cr2", SYS }, { "cr3", SYS }, { "cr4", SYS }, { "trp", GPR },
|
{ "rfx", GPR }, { "rip", GPR }, { "rbp", GPR }, { "rsp", GPR },
|
||||||
|
|
||||||
{ "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR },
|
{ "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR },
|
||||||
{ "rsi", GPR }, { "rdi", GPR }, { "rbp", GPR }, { "rsp", GPR },
|
{ "rsi", GPR }, { "rdi", GPR }, { "ax0", GPR }, { "ax1", GPR },
|
||||||
{ "rfx", GPR }, { "rip", GPR }, { "r10", GPR }, { "r11", GPR },
|
{ "ax2", GPR }, { "ax3", GPR }, { "ax4", GPR }, { "ax5", GPR },
|
||||||
{ "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR },
|
|
||||||
|
|
||||||
{ "ax0", GPR }, { "ax1", GPR }, { "ax2", GPR }, { "ax3", GPR },
|
{ "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR },
|
||||||
{ "ax4", GPR }, { "ax5", GPR }, { "ax6", GPR }, { "ax7", GPR },
|
{ "r16", GPR }, { "r17", GPR }, { "r18", GPR }, { "r19", GPR },
|
||||||
{ "nx0", GPR }, { "nx1", GPR }, { "nx2", GPR }, { "nx3", GPR },
|
{ "r20", GPR }, { "grp", GPR }, { "trp", GPR }, { "srp", SYS },
|
||||||
{ "nx4", GPR }, { "nx5", GPR }, { "nx6", GPR }, { "nx7", GPR },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, "");
|
static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, "");
|
||||||
@ -30,24 +28,20 @@ void dumpregs(ctx_t *ctx)
|
|||||||
TRACE("\n\nEnviron:");
|
TRACE("\n\nEnviron:");
|
||||||
TRACE("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", rpc, R(RIP), R(RFX));
|
TRACE("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", rpc, R(RIP), R(RFX));
|
||||||
TRACE("\nrsp=0x%-16lX rbp=0x%-16lX trp=0x%-16lX", R(RSP), R(RBP), R(TRP));
|
TRACE("\nrsp=0x%-16lX rbp=0x%-16lX trp=0x%-16lX", R(RSP), R(RBP), R(TRP));
|
||||||
|
TRACE("\nfc0=0x%-16lu cr0=0x%-16lX cr1=0x%-16lX", fc0, R(CR0), R(CR1));
|
||||||
TRACE("\n\nControl:");
|
|
||||||
TRACE("\ncr0=0x%-16lX cr1=0x%-16lX cr2=0x%-16lX", R(CR0), R(CR1), R(CR2));
|
|
||||||
TRACE("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu", fc0, fc1, fc2);
|
|
||||||
|
|
||||||
TRACE("\n\nArgument:");
|
TRACE("\n\nArgument:");
|
||||||
TRACE("\nax0=0x%-16lX ax1=0x%-16lX ax2=0x%-16lX", R(AX0), R(AX1), R(AX2));
|
TRACE("\nax0=0x%-16lX ax1=0x%-16lX ax2=0x%-16lX", R(AX0), R(AX1), R(AX2));
|
||||||
TRACE("\nax3=0x%-16lX ax4=0x%-16lX ax5=0x%-16lX", R(AX3), R(AX4), R(AX5));
|
TRACE("\nax3=0x%-16lX ax4=0x%-16lX ax5=0x%-16lX", R(AX3), R(AX4), R(AX5));
|
||||||
|
|
||||||
TRACE("\n\nVolatile:");
|
TRACE("\n\nVolatile:");
|
||||||
TRACE("\nrax=0x%-16lX rcx=0x%-16lX rdx=0x%-16lX", R(RAX), R(RCX), R(RDX));
|
TRACE("\nrax=0x%-16lX rbx=0x%-16lX rcx=0x%-16lX", R(RAX), R(RBX), R(RCX));
|
||||||
TRACE("\nr10=0x%-16lX r11=0x%-16lX r12=0x%-16lX", R(R10), R(R11), R(R12));
|
TRACE("\nrdx=0x%-16lX rsi=0x%-16lX rdi=0x%-16lX", R(RDX), R(RSI), R(RDI));
|
||||||
TRACE("\nr13=0x%-16lX r14=0x%-16lX r15=0x%-16lX", R(R13), R(R14), R(R15));
|
|
||||||
|
|
||||||
TRACE("\n\nPersistent:");
|
TRACE("\n\nPersistent:");
|
||||||
TRACE("\nrbx=0x%-16lX rdi=0x%-16lX rsi=0x%-16lX", R(RBX), R(RDI), R(RSI));
|
TRACE("\nr12=0x%-16lX r13=0x%-16lX r14=0x%-16lX", R(R12), R(R13), R(R14));
|
||||||
TRACE("\nnx0=0x%-16lX nx1=0x%-16lX nx2=0x%-16lX", R(NX0), R(NX1), R(NX2));
|
TRACE("\nr15=0x%-16lX r16=0x%-16lX r17=0x%-16lX", R(R15), R(R16), R(R17));
|
||||||
TRACE("\nnx3=0x%-16lX nx4=0x%-16lX nx5=0x%-16lX", R(NX3), R(NX4), R(NX5));
|
TRACE("\nr18=0x%-16lX r19=0x%-16lX r20=0x%-16lX", R(R18), R(R19), R(R20));
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
|
12
vm/pc/regs.h
12
vm/pc/regs.h
@ -37,21 +37,17 @@ struct reg_t
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
RZX, FC1, CR0, CR1, CR2, CR3, CR4, TRP,
|
RZX, CR0, CR1, CR2, RFX, RIP, RBP, RSP,
|
||||||
RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP,
|
RAX, RBX, RCX, RDX, RSI, RDI, AX0, AX1,
|
||||||
RFX, RIP, R10, R11, R12, R13, R14, R15,
|
AX2, AX3, AX4, AX5, R12, R13, R14, R15,
|
||||||
AX0, AX1, AX2, AX3, AX4, AX5, AX6, AX7,
|
R16, R17, R18, R19, R20, GRP, TRP, SRP,
|
||||||
NX0, NX1, NX2, NX3, NX4, NX5, NX6, NX7,
|
|
||||||
|
|
||||||
NREGS
|
NREGS
|
||||||
};
|
};
|
||||||
|
|
||||||
#define fc0 ctx->ninstrs
|
#define fc0 ctx->ninstrs
|
||||||
#define fc2 ctx->ni_thisfr
|
|
||||||
#define rpc ctx->cur_pc
|
#define rpc ctx->cur_pc
|
||||||
|
|
||||||
#define fc1 R(FC1)
|
|
||||||
|
|
||||||
#define rax R(RAX)
|
#define rax R(RAX)
|
||||||
#define rdx R(RDX)
|
#define rdx R(RDX)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user