1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
This commit is contained in:
julianb0 2019-06-21 19:38:31 +02:00
parent 18e97904e3
commit 27cb6a1b26
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
21 changed files with 376 additions and 167 deletions

View File

@ -6,7 +6,7 @@ KODIR=ka/obj
all: kas
kpc:
@cd vm && make --no-print-directory verbose=no
@cd vm && make --no-print-directory -s verbose=yes
kas: kpc as/regs.lst as/k-as.py
@cp vm/in/instrs.lst as

View File

@ -216,6 +216,17 @@ def parse():
#-------------------------------------------------------------------------------
escape_dict = {
'n': '\n',
't': '\t',
'r': '\r',
'v': '\v',
'f': '\f',
'"': '"',
'\'': '\'',
'\\': '\\',
}
def parse_preproc(line):
global pdata
@ -286,10 +297,9 @@ def parse_preproc(line):
if escaping:
escaping = False
if c == 'n':
c = '\n'
elif c == 't':
c = '\t'
if c in escape_dict:
c = escape_dict[c]
else:
print("Unrecognized escape sequence: {}".format(line))
leave()

1
ka/ABI
View File

@ -56,7 +56,6 @@ the function
- uses no local variables (on the stack)
- never uses any function that changes 'rbp' nor 'rsp',
aside from 'call' and 'ret'
- never calls a variadic function
You can never omit 'enter' without omitting 'leave', and vice-versa.

View File

@ -36,7 +36,7 @@ itoa:
j.z .fini
mov lx1, ax1
mod lx1, ax2 ; ax1 % base
rem lx1, ax2 ; ax1 % base
cmp lx1, 9 ; lx1 > 9 ?
j.a .nondec

View File

@ -20,8 +20,8 @@ include "crt/crt.k"
;
; Disk Operating System
;
include "sys/cpudev.k"
include "sys/memdev.k"
include "sys/drv/cpudev.k"
include "sys/drv/memdev.k"
include "sys/tests.k"
include "sys/main.k"

View File

@ -5,5 +5,6 @@
; Main function
;
main:
call keybd_test
ret

View File

@ -1,6 +1,19 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
keybd_test:
.1:
scan rax
xpause
test rax, rax
j.z .1
prn rax
jmp .1
ret
putc_scroll_test:
mov rdx, 25
.1:

View File

@ -39,9 +39,9 @@ $(OBJDIR)/%.o: %.c
$(OBJDIR)/%.d: %.c
@mkdir -p $(shell dirname $@)
@cc -I. -MM -MT $(@:%.d=%.o) -MF $@ $<
@if [ $(verbose) = "yes" ]; then \
echo ${CL2}[$@] ${CL}dependencies generated.${CL3};\
fi
#@if [ $(verbose) = "yes" ]; then \
# echo ${CL2}[$@] ${CL}dependencies generated.${CL3};\
#fi
in/instrs.lst: in/INSTRS in/arch_i.py
@cd in && python3 arch_i.py

View File

@ -183,13 +183,13 @@ mulf rm rim
div rm rim
#
# Arithmetical unsigned MOD operation
# Arithmetical unsigned modulo operation (REM)
#
# $1 = $1 MOD $2
#
# Preserves all flags
#
mod rm rim
rem rm rim
#
# Arithmetical unsigned 128-bit MUL operation
@ -382,10 +382,34 @@ push rim
#
pop rm
#---------------------------------------------------------------------------#
# I/O instructions #
#---------------------------------------------------------------------------#
#
# Send a character to standard output (PRN)
#
prn rim
#
# Scan a character from standard input (SCAN)
#
scan rm
#---------------------------------------------------------------------------#
# Supervisor only instructions #
#---------------------------------------------------------------------------#
#
# Halt the processor until next E/I (HLT)
#
hlt
#
# Pause the CPU for a relatively long time (XPAUSE)
#
xpause
#
# Call an architecture-reserved function slot of device (DEVCTL)
#
@ -400,6 +424,122 @@ devctl rim rim
#
iocall rim rim
#---------------------------------------------------------------------------#
# E/I handling instructions #
#---------------------------------------------------------------------------#
#
# Trap into exception handler (TRAP)
#
# Throw:
# #ILL if $1 > 255
# #($1+256) otherwise
#
trap rim
#
# Return from exception/interrupt (IRET)
#
iret
#---------------------------------------------------------------------------#
# Misc. instructions #
#---------------------------------------------------------------------------#
#
# Do nothing (NOOP)
#
# (nothing)
#
# Throws:
# (nothing)
#
# Preserves all flags
#
nop
#
# Pause the CPU for a very short amount of time (PAUSE)
# Used in spin-like loops
#
pause
#
# CPU Identification Number
#
# Does nothing (for now)
#
cpuid
#
# Pseudo-random number generation (RAND32/RAND64)
#
# RAND32 generates a 32-bit pseudo-random number using
# a nonlinear additive feedback pseudo-random number generator
# of period 16 * (2^31 - 1).
#
# RAND64 generates two such numbers, and store them in the destination
# operand's higher and lower double words respectively
#
# The running program does not control the seeding and the processor
# may generate numbers from the same generator for other purposes
# than this instruction
#
#rand32 rm
#rand64 rm
#
# Get code/data offset (GCO/GCD)
#
# $1 = CR1 (GCO)
# $1 = CR2 (GCD)
#
gco rm
gcd rm
#---------------------------------------------------------------------------#
# Debugging instructions #
#---------------------------------------------------------------------------#
#
# Breakpoint instruction (BREAK)
#
# (cause register dump on standard error)
# (wait for user input before proceeeding)
#
break
#
# Step-by-step execution (STEP)
#
# IF $1 == 0 THEN
# (disable step-by-step execution)
# ELSE
# (enable step-by-step execution)
# FI
#
step rim
#---------------------------------------------------------------------------#
# Clean-up misc. instructions #
#---------------------------------------------------------------------------#
#
# Clear base volatile registers (CLR)
#
# RAX = RBX = RCX = RDX = 0
# RSX = RBI = RDI = RSI = 0
#
clr
#
# Clear argument registers (CLA)
#
# AX0 = AX1 = AX2 = AX3 = 0
# AX4 = AX5 = AX6 = AX7 = 0
#
cla
#---------------------------------------------------------------------------#
# Flag manipulation instructions #
#---------------------------------------------------------------------------#
@ -455,127 +595,6 @@ bswap rm rim
wswap rm rim
dswap rm rim
#---------------------------------------------------------------------------#
# E/I handling instructions #
#---------------------------------------------------------------------------#
#
# Trap into exception handler (TRAP)
#
# Throw:
# #ILL if $1 > 255
# #($1+256) otherwise
#
trap rim
#
# Return from exception/interrupt (IRET)
#
iret
hlt
#---------------------------------------------------------------------------#
# Misc. instructions #
#---------------------------------------------------------------------------#
#
# Do nothing (NOOP)
#
# (nothing)
#
# Throws:
# (nothing)
#
# Preserves all flags
#
nop
#
# CPU Identification Number
#
# Does nothing (for now)
#
cpuid
#
# Pseudo-random number generation (RAND32/RAND64)
#
# RAND32 generates a 32-bit pseudo-random number using
# a nonlinear additive feedback pseudo-random number generator
# of period 16 * (2^31 - 1).
#
# RAND64 generates two such numbers, and store them in the destination
# operand's higher and lower double words respectively
#
# The running program does not control the seeding and the processor
# may generate numbers from the same generator for other purposes
# than this instruction
#
#rand32 rm
#rand64 rm
#
# Get code/data offset (GCO/GCD)
#
# $1 = CR1 (GCO)
# $1 = CR2 (GCD)
#
gco rm
gcd rm
#
# Send a character to standard output (PRN)
#
# Throws:
# #PRN if DV text mode enabled
# #PRN if graphic mode enabled
#
prn rim
#---------------------------------------------------------------------------#
# Debugging instructions #
#---------------------------------------------------------------------------#
#
# Breakpoint instruction (BREAK)
#
# (cause register dump on standard error)
# (wait for user input before proceeeding)
#
break
#
# Step-by-step execution (STEP)
#
# IF $1 == 0 THEN
# (disable step-by-step execution)
# ELSE
# (enable step-by-step execution)
# FI
#
step rim
#---------------------------------------------------------------------------#
# Clean-up misc. instructions #
#---------------------------------------------------------------------------#
#
# Clear base volatile registers (CLR)
#
# RAX = RBX = RCX = RDX = 0
# RSX = RBI = RDI = RSI = 0
#
clr
#
# Clear argument registers (CLA)
#
# AX0 = AX1 = AX2 = AX3 = 0
# AX4 = AX5 = AX6 = AX7 = 0
#
cla
#---------------------------------------------------------------------------#
# String manipulation instructions #
#---------------------------------------------------------------------------#

View File

@ -220,7 +220,7 @@ IMPL_START_2(div)
}
IMPL_OUT;
IMPL_START_2(mod)
IMPL_START_2(rem)
{
v1 %= v2;
}

27
vm/in/inout.c Normal file
View File

@ -0,0 +1,27 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <in/instrs.h>
#include <pc/console.h>
//----------------------------------------------------------------------------//
IMPL_START_1(prn)
{
if (p1->mlen > 1) {
trace("prn warning: large access size\n");
}
console_putc(ctx, (char)v1);
}
IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_1(scan)
{
v1 = console_scankeybuf(ctx);
}
IMPL_OUT;
//----------------------------------------------------------------------------//

View File

@ -3,6 +3,7 @@
#include <in/instrs.h>
#include <sys/time.h>
#include <unistd.h>
#include <pc/console.h>
@ -18,6 +19,21 @@ IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_0(pause)
{
usleep(5000);
}
IMPL_END;
IMPL_START_0(xpause)
{
CHK_SUPERV();
usleep(25000);
}
IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_0(cpuid)
{
rax = rdx = 0;
@ -50,17 +66,6 @@ IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_1(prn)
{
if (p1->mlen > 1) {
trace("prn warning: large access size\n");
}
console_putc(ctx, (char)v1);
}
IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_0(clr)
{
rax = rbx = rcx = rdx = 0;

View File

@ -77,6 +77,9 @@ void console_exit(ctx_t *ctx)
SDL_DestroyTexture(scr_texts[y]);
}
if (scr_rend)
SDL_DestroyRenderer(scr_rend);
if (scr_win)
SDL_DestroyWindow(scr_win);
@ -102,6 +105,27 @@ void console_render(ctx_t *ctx)
//----------------------------------------------------------------------------//
void console_update(ctx_t *ctx)
{
SDL_Event evt;
if (__builtin_expect(SDL_PollEvent(&evt) == 1, 0))
{
switch (evt.type)
{
case SDL_QUIT:
die(0);
break;
case SDL_KEYDOWN:
console_handle_input(ctx, evt.key.keysym.sym);
break;
}
}
}
//----------------------------------------------------------------------------//
void console_putat(ctx_t *ctx, char ch, int x, int y)
{
SDL_Surface *surf;
@ -172,16 +196,28 @@ void console_putc(ctx_t *ctx, char ch)
{
size_t y;
if (ch < ' ' && ch != '\n')
ch = 127;
if (ch == '\n')
csn_x = CONSOLE_WIDTH;
else
switch (ch)
{
console_putat(ctx, ch, csn_x, csn_y);
csn_x++;
case '\n':
csn_x = CONSOLE_WIDTH;
break;
case '\r':
csn_x = 0;
return;
case '\b':
if (csn_x == 0)
return;
csn_x--;
console_putat(ctx, ' ', csn_x, csn_y);
break;
default:
console_putat(ctx, ch, csn_x, csn_y);
csn_x++;
break;
}
if (csn_x == CONSOLE_WIDTH)

View File

@ -1,9 +1,11 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Critical ordering
#include <pc/arch.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <pc/keybd.h>
void console_init(ctx_t *ctx);
void console_exit(ctx_t *ctx);
@ -11,4 +13,7 @@ void console_exit(ctx_t *ctx);
void console_render(ctx_t *ctx);
void console_putat(ctx_t *ctx, char ch, int x, int y);
void console_putc(ctx_t *ctx, char ch);
void console_update(ctx_t *ctx);
void console_handle_input(ctx_t *, SDL_Keycode);

View File

@ -20,8 +20,7 @@ enum
E_DBF, // Double fault
E_IMP, // Not implemented
E_ALI, // Alignment error
E_STA, // Stack misalignment
E_STU, // Stack underflow
E_BRK, // Ctrl+C or similar
NEXCPTS
};

84
vm/pc/keybd.c Normal file
View File

@ -0,0 +1,84 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <pc/console.h>
#define KEYBUFSIZE 8192
typedef uint keycode_t;
keycode_t keybuf[KEYBUFSIZE] = { 0 };
keycode_t *keybuf_last = &keybuf[0];
keycode_t *keybuf_ptr = &keybuf[0];
void console_addkey(ctx_t *ctx, keycode_t key)
{
*keybuf_ptr++ = key;
if (keybuf_ptr == keybuf + KEYBUFSIZE)
keybuf_ptr = &keybuf[0];
}
keycode_t console_getkey(ctx_t *ctx)
{
keycode_t rc = *keybuf_last++;
if (keybuf_last == keybuf + KEYBUFSIZE)
keybuf_last = &keybuf[0];
return rc;
}
keycode_t console_scankeybuf(ctx_t *ctx)
{
if (keybuf_last != keybuf_ptr)
return console_getkey(ctx);
return 0;
}
void console_handle_input(ctx_t *ctx, SDL_Keycode key)
{
keycode_t code = 0;
SDL_Keymod mod = SDL_GetModState();
if (key <= 'z' && key >= 'a')
{
if (mod & (KMOD_CTRL|KMOD_ALT))
{
if (key == 'c')
_except(ctx, E_BRK, "Ctrl+C received");
return;
}
if (mod & KMOD_SHIFT)
key -= ('a' - 'A');
console_addkey(ctx, key);
return;
}
if (key <= '0' && key >= '9')
console_addkey(ctx, key);
switch (key)
{
case SDLK_SPACE: code = ' '; break;
case SDLK_BACKSLASH: code = '\\'; break;
case SDLK_BACKSPACE: code = '\b'; break;
case SDLK_RETURN:
case SDLK_RETURN2:
code = '\n';
break;
default:
return;
}
console_addkey(ctx, code);
}

17
vm/pc/keybd.h Normal file
View File

@ -0,0 +1,17 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#define KEYBUFSIZE 8192
typedef uint keycode_t;
extern keycode_t keybuf[KEYBUFSIZE];
extern keycode_t *keybuf_last;
extern keycode_t *keybuf_ptr;
keycode_t console_getkey(ctx_t *);
keycode_t console_scankeybuf(ctx_t *);
void console_addkey(ctx_t *, keycode_t);
void console_handle_input(ctx_t *ctx, SDL_Keycode key);

View File

@ -34,7 +34,7 @@ ctx_t main_ctx;
void sigcommon(void)
{
_except(&main_ctx, 1023, "SIGNAL'ed");
_except(&main_ctx, E_BRK, "SIGNAL'ed");
}
void sigint(int _)
@ -53,8 +53,6 @@ void sigsegv(int _)
//
void main_loop(void)
{
SDL_Event evt;
//
// Start decoding
//
@ -62,11 +60,7 @@ void main_loop(void)
// Execute one instruction
decode(&main_ctx);
if (__builtin_expect(SDL_PollEvent(&evt) == 1, 0))
{
if (evt.type == SDL_QUIT)
die(0);
}
console_update(&main_ctx);
if (main_ctx.step)
getchar();

View File

@ -22,7 +22,7 @@ int create_symtab(const char *name)
{
// log("SYM: '%.*s' '%lu'\n", SYMLEN_MAX, buf, addr);
if (prev_addr >= addr)
if (prev_addr > addr)
{
logerr("Symbol addresses in symbol table not in increasing order\n");
logerr("Previous symbol: '%s' '%lu'\n", symtab[it-1].name, prev_addr);