mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
ka
This commit is contained in:
parent
c6779c0ea2
commit
7f22cd93da
@ -1,23 +1,6 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
_doprnt_test:
|
||||
mov ax0, .fmt
|
||||
sub rsp, 128
|
||||
mov q[rsp+40], 0x7FE
|
||||
mov q[rsp+32], -2
|
||||
mov q[rsp+24], 666
|
||||
mov q[rsp+16], 0x112233DDAA6677BB
|
||||
mov q[rsp+8], 'K'
|
||||
mov q[rsp], .str
|
||||
call printf
|
||||
add rsp, 128
|
||||
|
||||
ret
|
||||
|
||||
.fmt = "%% Hello World %s - %c - %p - %d - %d - %b"
|
||||
.str = "(cc)"
|
||||
|
||||
;
|
||||
; typedef int (*PUTC)(int ch)
|
||||
; int _doprnt(PUTC putc, int n, const char *fmt, va_list ap)
|
||||
@ -142,15 +125,15 @@ _doprnt:
|
||||
jmp .print_number
|
||||
|
||||
.print_number:
|
||||
; allocate itoa convertion buffer
|
||||
; allocate itoa conversion buffer
|
||||
sub rsp, 80
|
||||
mov rdi, rsp
|
||||
|
||||
; assume modifier already set up ax2 and ax3
|
||||
mov ax0, rsp
|
||||
mov ax1, q[rsi + nx2 * 8]
|
||||
inc nx2
|
||||
call _itoa
|
||||
inc nx2
|
||||
|
||||
.print_itoa_buf:
|
||||
mov ax0, b[rdi]
|
||||
|
@ -25,22 +25,22 @@ _itoa:
|
||||
; make sure base is in [2, 32]
|
||||
|
||||
cmp ax2, 2
|
||||
jmp.b .bad
|
||||
j.b .bad
|
||||
|
||||
cmp ax2, 36
|
||||
jmp.a .bad
|
||||
j.a .bad
|
||||
|
||||
; deal with zero
|
||||
test ax1, ax1
|
||||
jmp.z .zero
|
||||
j.z .zero
|
||||
|
||||
; deal with base 10 signedness
|
||||
|
||||
test ax3, ax3 ; unsigned mode
|
||||
jmp.nz .conv
|
||||
j.nz .conv
|
||||
|
||||
cmp ax2, 10 ; base 10
|
||||
jmp.nz .conv
|
||||
j.nz .conv
|
||||
|
||||
sgn lx0, ax1 ; extract ax1 sign
|
||||
|
||||
@ -50,13 +50,13 @@ _itoa:
|
||||
; main loop
|
||||
.conv:
|
||||
test ax1, ax1
|
||||
jmp.z .fini
|
||||
j.z .fini
|
||||
|
||||
mov lx1, ax1
|
||||
mod lx1, ax2 ; ax1 % base
|
||||
|
||||
cmp lx1, 9 ; lx1 > 9 ?
|
||||
jmp.a .nondec
|
||||
j.a .nondec
|
||||
|
||||
add lx1, '0'
|
||||
jmp .next
|
||||
|
@ -13,16 +13,11 @@ putc:
|
||||
; int printf(const char *fmt, ...)
|
||||
;
|
||||
printf:
|
||||
enter 0
|
||||
|
||||
mov ax2, ax0
|
||||
mov ax0, putc
|
||||
mov ax1, STRLEN_MAX
|
||||
lea ax3, b[rbp+16]
|
||||
call _doprnt
|
||||
|
||||
leave
|
||||
ret
|
||||
lea ax3, b[rsp+8]
|
||||
jmp _doprnt
|
||||
|
||||
;
|
||||
; Print a string
|
||||
|
@ -27,7 +27,7 @@ strnzcpy:
|
||||
ret.cxz
|
||||
|
||||
dec rcx
|
||||
jmp.cxz .1
|
||||
j.cxz .1
|
||||
|
||||
movsb.rep.nz ax0, ax1
|
||||
|
||||
|
@ -54,7 +54,7 @@ strrev2:
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.2:
|
||||
cmp ax0, ax1
|
||||
jmp.ae .3
|
||||
j.ae .3
|
||||
|
||||
xchg b[ax0], b[ax1]
|
||||
|
||||
|
24
ka/main.k
24
ka/main.k
@ -5,7 +5,7 @@
|
||||
; Main function
|
||||
;
|
||||
main:
|
||||
call _doprnt_test
|
||||
call showoff
|
||||
ret
|
||||
|
||||
showoff:
|
||||
@ -15,8 +15,26 @@ showoff:
|
||||
prn 10
|
||||
call str_test
|
||||
call movzx_test
|
||||
prn 10
|
||||
call printf_test
|
||||
ret
|
||||
|
||||
printf_test:
|
||||
mov ax0, .fmt
|
||||
sub rsp, 128
|
||||
mov q[rsp+40], 0x7FE
|
||||
mov q[rsp+32], -2
|
||||
mov q[rsp+24], 666
|
||||
mov q[rsp+16], 0x112233DDAA6677BB
|
||||
mov q[rsp+8], 'K'
|
||||
mov q[rsp], .str
|
||||
call printf
|
||||
add rsp, 128
|
||||
ret
|
||||
|
||||
.fmt = "%% Hello World %s - %c - %p - %d - %d - %b"
|
||||
.str = "(cc)"
|
||||
|
||||
strchr_test:
|
||||
mov rax, 0
|
||||
mov ax0, .str
|
||||
@ -58,8 +76,8 @@ movzx_test:
|
||||
|
||||
movzx rsx, b[rsp]
|
||||
movzx rbi, w[rsp]
|
||||
movzx rdi, l[rsp]
|
||||
movzx rsi, q[rsp]
|
||||
movzx rsi, l[rsp]
|
||||
movzx rdi, q[rsp]
|
||||
|
||||
leave
|
||||
ret
|
||||
|
@ -3,14 +3,11 @@
|
||||
|
||||
MEMDEV := 1
|
||||
|
||||
MEMDEV_GETMEMOFF := 0
|
||||
MEMDEV_GETMEMSIZE := 1
|
||||
|
||||
MEM.GetMemOff:
|
||||
iocall MEMDEV, MEMDEV_GETMEMOFF
|
||||
iocall MEMDEV, 0
|
||||
ret
|
||||
|
||||
MEM.GetMemSize:
|
||||
iocall MEMDEV, MEMDEV_GETMEMSIZE
|
||||
iocall MEMDEV, 1
|
||||
ret
|
||||
|
||||
|
@ -10,14 +10,14 @@
|
||||
IMPL_START_0(cli)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
flg &= ~IF;
|
||||
cr0 &= ~IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(sti)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
flg |= IF;
|
||||
cr0 |= IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
|
@ -41,7 +41,13 @@ void vlog(const char *, va_list);
|
||||
|
||||
struct ctx_t
|
||||
{
|
||||
// Array of NREGS ulong's
|
||||
ulong *rf;
|
||||
|
||||
// Register (names & types) table
|
||||
reg_t *r;
|
||||
|
||||
// Instruction table
|
||||
instr_t *i;
|
||||
|
||||
// Memory and memory size
|
||||
@ -58,7 +64,7 @@ struct ctx_t
|
||||
dev_t *dh;
|
||||
};
|
||||
|
||||
#define R(X) ctx->r[X].val
|
||||
#define R(X) ctx->rf[X]
|
||||
|
||||
void dumpregs(ctx_t *);
|
||||
void dumpinstr(ctx_t *, ulong, uint, ushort, acc_t *, acc_t *);
|
||||
|
38
vm/pc/main.c
38
vm/pc/main.c
@ -90,48 +90,70 @@ int main(int argc, char **argv)
|
||||
exit(-3);
|
||||
}
|
||||
|
||||
fwprog = malloc(FWPROGSIZE);
|
||||
fwfile = fopen(argv[1], "rb");
|
||||
|
||||
if (!fwprog) {
|
||||
log("Couldn't allocate firmware buffer\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (!fwfile) {
|
||||
log("Couldn't open program file\n");
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
fwprog = malloc(FWPROGSIZE);
|
||||
|
||||
if (!fwprog) {
|
||||
log("Couldn't allocate firmware buffer\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fwsize = fread(fwprog, 1, FWPROGSIZE, fwfile);
|
||||
|
||||
if (fwsize < 2) {
|
||||
log("Program file too small or empty\n");
|
||||
free(fwprog);
|
||||
exit(-3);
|
||||
}
|
||||
|
||||
fclose(fwfile);
|
||||
|
||||
//
|
||||
// Register frame allocation
|
||||
//
|
||||
main_ctx.rf = calloc(NREGS, sizeof(ulong));
|
||||
|
||||
//
|
||||
// Memory allocation
|
||||
//
|
||||
main_ctx.mp = malloc(MEMSIZE + 16);
|
||||
main_ctx.mz = MEMSIZE;
|
||||
|
||||
main_ctx.get = bget;
|
||||
|
||||
main_ctx.r[RIP].val = MEMOFF;
|
||||
main_ctx.rf[RIP] = MEMOFF;
|
||||
|
||||
if (main_ctx.mp == 0) {
|
||||
log("Couldn't allocate RAM\n");
|
||||
free(main_ctx.rf);
|
||||
free(fwprog);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memcpy(&main_ctx.mp[addr2real(main_ctx.r[RIP].val)], fwprog, fwsize);
|
||||
memcpy(&main_ctx.mp[addr2real(main_ctx.rf[RIP])], fwprog, fwsize);
|
||||
|
||||
//
|
||||
// Devices initialization
|
||||
//
|
||||
main_ctx.dh = 0;
|
||||
if (devinitall(&main_ctx) < 0) {
|
||||
log("Couldn't initialize devices\n");
|
||||
free(main_ctx.rf);
|
||||
free(fwprog);
|
||||
exit(-10);
|
||||
}
|
||||
|
||||
disable_stdin_echoing();
|
||||
|
||||
//
|
||||
// Start decoding
|
||||
//
|
||||
while (1) {
|
||||
decode(&main_ctx);
|
||||
|
||||
|
129
vm/pc/regs.c
129
vm/pc/regs.c
@ -5,83 +5,70 @@
|
||||
|
||||
reg_t arch_r[] =
|
||||
{
|
||||
// Invalid register
|
||||
{ "inv", 0, RES },
|
||||
|
||||
// Instruction pointer
|
||||
{ "rip", 0, RES },
|
||||
|
||||
// Flags register
|
||||
{ "flg", 0, RES },
|
||||
{ "inv", RES },
|
||||
{ "rip", RES },
|
||||
{ "flg", RES },
|
||||
|
||||
// Stack registers
|
||||
{ "rbp", 0, GPR },
|
||||
{ "rsp", 0, GPR },
|
||||
{ "rbp", GPR },
|
||||
{ "rsp", GPR },
|
||||
|
||||
// Reserved registers
|
||||
{ "rx0", 0, RES },
|
||||
{ "rx1", 0, RES },
|
||||
{ "rx2", 0, RES },
|
||||
{ "rx0", RES },
|
||||
{ "rx1", RES },
|
||||
{ "rx2", RES },
|
||||
|
||||
// General-purpose volatile registers
|
||||
{ "rax", 0, GPR },
|
||||
{ "rbx", 0, GPR },
|
||||
{ "rcx", 0, GPR },
|
||||
{ "rdx", 0, GPR },
|
||||
{ "rsx", 0, GPR },
|
||||
{ "rbi", 0, GPR },
|
||||
{ "rsi", 0, GPR },
|
||||
{ "rdi", 0, GPR },
|
||||
{ "rax", GPR },
|
||||
{ "rbx", GPR },
|
||||
{ "rcx", GPR },
|
||||
{ "rdx", GPR },
|
||||
{ "rsx", GPR },
|
||||
{ "rbi", GPR },
|
||||
{ "rsi", GPR },
|
||||
{ "rdi", GPR },
|
||||
|
||||
// General-purpose non-volatile registers
|
||||
{ "nx0", 0, GPR },
|
||||
{ "nx1", 0, GPR },
|
||||
{ "nx2", 0, GPR },
|
||||
{ "nx3", 0, GPR },
|
||||
{ "nx4", 0, GPR },
|
||||
{ "nx5", 0, GPR },
|
||||
{ "nx6", 0, GPR },
|
||||
{ "nx7", 0, GPR },
|
||||
{ "nx0", GPR },
|
||||
{ "nx1", GPR },
|
||||
{ "nx2", GPR },
|
||||
{ "nx3", GPR },
|
||||
{ "nx4", GPR },
|
||||
{ "nx5", GPR },
|
||||
{ "nx6", GPR },
|
||||
{ "nx7", GPR },
|
||||
|
||||
// Argument registers; volatile
|
||||
{ "ax0", 0, GPR },
|
||||
{ "ax1", 0, GPR },
|
||||
{ "ax2", 0, GPR },
|
||||
{ "ax3", 0, GPR },
|
||||
{ "ax4", 0, GPR },
|
||||
{ "ax5", 0, GPR },
|
||||
{ "ax6", 0, GPR },
|
||||
{ "ax7", 0, GPR },
|
||||
{ "ax0", GPR },
|
||||
{ "ax1", GPR },
|
||||
{ "ax2", GPR },
|
||||
{ "ax3", GPR },
|
||||
{ "ax4", GPR },
|
||||
{ "ax5", GPR },
|
||||
{ "ax6", GPR },
|
||||
{ "ax7", GPR },
|
||||
|
||||
// Leaf function registers; volatile
|
||||
{ "lx0", 0, GPR },
|
||||
{ "lx1", 0, GPR },
|
||||
{ "lx2", 0, GPR },
|
||||
{ "lx3", 0, GPR },
|
||||
{ "lx4", 0, GPR },
|
||||
{ "lx5", 0, GPR },
|
||||
{ "lx6", 0, GPR },
|
||||
{ "lx7", 0, GPR },
|
||||
{ "lx0", GPR },
|
||||
{ "lx1", GPR },
|
||||
{ "lx2", GPR },
|
||||
{ "lx3", GPR },
|
||||
{ "lx4", GPR },
|
||||
{ "lx5", GPR },
|
||||
{ "lx6", GPR },
|
||||
{ "lx7", GPR },
|
||||
|
||||
// Control register
|
||||
{ "cr0", 0, CTL },
|
||||
{ "cr1", 0, CTL },
|
||||
{ "cr2", 0, CTL },
|
||||
{ "cr3", 0, CTL },
|
||||
{ "cr4", 0, CTL },
|
||||
{ "cr5", 0, CTL },
|
||||
{ "cr6", 0, CTL },
|
||||
{ "cr7", 0, CTL },
|
||||
{ "cr0", CTL },
|
||||
{ "cr1", CTL },
|
||||
{ "cr2", CTL },
|
||||
{ "cr3", CTL },
|
||||
{ "cr4", CTL },
|
||||
{ "cr5", CTL },
|
||||
{ "cr6", CTL },
|
||||
{ "cr7", CTL },
|
||||
|
||||
// System-reserved
|
||||
{ "sa0", 0, SYS },
|
||||
{ "sa1", 0, SYS },
|
||||
{ "sa2", 0, SYS },
|
||||
{ "sa3", 0, SYS },
|
||||
{ "sa4", 0, SYS },
|
||||
{ "sa5", 0, SYS },
|
||||
{ "sa6", 0, SYS },
|
||||
{ "sa7", 0, SYS },
|
||||
{ "sa0", SYS },
|
||||
{ "sa1", SYS },
|
||||
{ "sa2", SYS },
|
||||
{ "sa3", SYS },
|
||||
{ "sa4", SYS },
|
||||
{ "sa5", SYS },
|
||||
{ "sa6", SYS },
|
||||
{ "sa7", SYS },
|
||||
};
|
||||
|
||||
#define DUMPREGS(down, up) \
|
||||
@ -89,7 +76,7 @@ reg_t arch_r[] =
|
||||
if (i % 4 == 0) \
|
||||
log("\n"); \
|
||||
r = &ctx->r[i]; \
|
||||
log("%s=0x%-16lX ", r->name, r->val); \
|
||||
log("%s=0x%-16lX ", r->name, R(i)); \
|
||||
} \
|
||||
|
||||
void dumpregs(ctx_t *ctx)
|
||||
@ -119,6 +106,6 @@ void dumpregs(ctx_t *ctx)
|
||||
!!(flg&CF), !!(flg&OF),
|
||||
!!(flg&ZF), !!(flg&SF),
|
||||
!!(flg&PF), !!(flg&DF),
|
||||
!!(flg&IF), !!(cr0&UF));
|
||||
!!(cr0&IF), !!(cr0&UF));
|
||||
}
|
||||
|
||||
|
@ -22,20 +22,18 @@ enum
|
||||
|
||||
PF = 1 << 4, // Parity flag
|
||||
DF = 1 << 5, // Direction flag
|
||||
|
||||
IF = 1 << 16, // Interrupts enable flag
|
||||
};
|
||||
|
||||
// CR0 register
|
||||
enum
|
||||
{
|
||||
UF = 1 << 15, // User-mode flag
|
||||
IF = 1 << 16, // Interrupts enable flag
|
||||
};
|
||||
|
||||
struct reg_t
|
||||
{
|
||||
char *name;
|
||||
ulong val;
|
||||
ulong flags;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user