mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
instrs
This commit is contained in:
parent
4bccea4a9d
commit
49ad38a774
2
Makefile
2
Makefile
@ -19,7 +19,7 @@ $(KODIR)/a.out: $(DOSK) kas
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@cd vm && make clean --no-print-directory
|
||||
@rm -f $(KODIR)/a.out $(KODIR)/a.out.sym $(KODIR)/k.exe $(KODIR)/stdout.txt as/instrs.lst
|
||||
@rm -f $(KODIR)/a.out $(KODIR)/a.out.sym $(KODIR)/k.exe as/instrs.lst
|
||||
|
||||
test: $(KODIR)/a.out
|
||||
@vm/k.exe $(KODIR)/a.out $(KODIR)/a.sym
|
||||
|
158
vm/in/ARITH
Normal file
158
vm/in/ARITH
Normal file
@ -0,0 +1,158 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Arithmetic instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# CMP Comparison instruction
|
||||
#
|
||||
# $1 - $2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
cmp rim rim
|
||||
|
||||
#
|
||||
# Arithmetical SGN operation
|
||||
#
|
||||
# IF ($1 == 0) THEN
|
||||
# $2 = 0
|
||||
# ELIF ($1 GT 0) THEN
|
||||
# $2 = 1
|
||||
# ELSE
|
||||
# $2 = LONG_MIN
|
||||
# FI
|
||||
#
|
||||
# Treats $1 and $2 as signed values
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
sgn rm rim
|
||||
sgnf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical NEG operation
|
||||
#
|
||||
# $1 = NOT($1) + 1
|
||||
#
|
||||
# Sets CF if $1 == 0; clears it otherwise
|
||||
# Sets OF if $1 == $LONG_MIN; clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
neg rm
|
||||
negf rm
|
||||
|
||||
#
|
||||
# Arithmetical INC operation
|
||||
#
|
||||
# $1 = $1 + 1
|
||||
#
|
||||
# Preserves CF
|
||||
# Sets OF if $1 == $LONG_MAX, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
inc rm
|
||||
incf rm
|
||||
|
||||
#
|
||||
# Arithmetical DEC operation
|
||||
#
|
||||
# $1 = $1 - 1
|
||||
#
|
||||
# Preserves CF
|
||||
# Sets OF if $1 == $LONG_MIN, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
dec rm
|
||||
decf rm
|
||||
|
||||
#
|
||||
# Arithmetical ADD operation
|
||||
#
|
||||
# $1 = $1 + $2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
add rm rim
|
||||
addf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical ADD operation, with carry
|
||||
#
|
||||
# $1 = $1 + $2 + CF
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
adc rm rim
|
||||
adcf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical SUB operation
|
||||
#
|
||||
# $1 = $1 - $2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
sub rm rim
|
||||
subf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned MUL operation
|
||||
#
|
||||
# $1 = LO($1 * $2)
|
||||
#
|
||||
# Sets CF and OF if HI($1 * $2) > 0, clears them otherwise
|
||||
# Preserves ZF and SF
|
||||
#
|
||||
mul rm rim
|
||||
mulf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned DIV operation
|
||||
#
|
||||
# $1 = $1 DIV $2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
div rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned modulo operation (REM)
|
||||
#
|
||||
# $1 = $1 MOD $2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
rem rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned 128-bit MUL operation
|
||||
#
|
||||
# RDX = HI(RAX * $1)
|
||||
# RAX = LO(RAX * $1)
|
||||
#
|
||||
# Sets CF and OF if HI($1 * $2) > 0, clears them otherwise
|
||||
# Preserves ZF and SF
|
||||
#
|
||||
mul2 rim
|
||||
mul2f rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned combined DIV and MOD operations
|
||||
#
|
||||
# RDX = (RAX MOD $1)
|
||||
# RAX = (RAX DIV $1)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
div2 rim
|
||||
|
26
vm/in/DEBUG
Normal file
26
vm/in/DEBUG
Normal file
@ -0,0 +1,26 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# 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
|
||||
|
45
vm/in/FLAGS
Normal file
45
vm/in/FLAGS
Normal file
@ -0,0 +1,45 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Flag manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Clear or set interrupt flag (CLI/STI)
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
cli
|
||||
sti
|
||||
|
||||
#
|
||||
# Clear or set direction flag (CLD/STD)
|
||||
#
|
||||
cld
|
||||
std
|
||||
|
||||
#
|
||||
# Complement, clear or set carry flag (CMC/CLC/STC)
|
||||
#
|
||||
cmc
|
||||
clc
|
||||
stc
|
||||
|
||||
#
|
||||
# Load FLG register (LODF)
|
||||
#
|
||||
# $1 = FLG
|
||||
#
|
||||
lodf rm
|
||||
|
||||
#
|
||||
# Store FLG register - lower byte only (STOFB)
|
||||
#
|
||||
# FLG[7:0] = $1[7:0]
|
||||
#
|
||||
# Note: FLG's lower byte contains CF, OF, ZF, SF, PF and DF
|
||||
#
|
||||
stofb rm
|
||||
|
17
vm/in/INOUT
Normal file
17
vm/in/INOUT
Normal 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.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# I/O instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Send a character to standard output (PRN)
|
||||
#
|
||||
prn rim
|
||||
|
||||
#
|
||||
# Scan a character from standard input (SCAN)
|
||||
#
|
||||
scan rm
|
||||
|
737
vm/in/INSTRS
737
vm/in/INSTRS
@ -5,729 +5,16 @@
|
||||
# Special instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Initiate machine shutdown (STOP)
|
||||
#
|
||||
# THROW #SHT
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
# #ILL if disabled through DV
|
||||
# #SHT otherwise
|
||||
#
|
||||
stop
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Logical instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Bitwise NOT operation
|
||||
#
|
||||
# $1 = NOT($1)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
not rm
|
||||
|
||||
#
|
||||
# Bitwise OR operation
|
||||
#
|
||||
# $1 = $1 OR $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
or rm rim
|
||||
orf rm rim
|
||||
|
||||
#
|
||||
# Bitwise AND operation
|
||||
#
|
||||
# $1 = $1 AND $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
and rm rim
|
||||
andf rm rim
|
||||
|
||||
#
|
||||
# Bitwise XOR operation
|
||||
#
|
||||
# $1 = $1 XOR $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
xor rm rim
|
||||
xorf rm rim
|
||||
|
||||
# To document
|
||||
shl rm rim
|
||||
shr rm rim
|
||||
shlf rm rim
|
||||
shrf rm rim
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Arithmetic instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Arithmetical SGN operation
|
||||
#
|
||||
# IF ($1 == 0) THEN
|
||||
# $2 = 0
|
||||
# ELIF ($1 GT 0) THEN
|
||||
# $2 = 1
|
||||
# ELSE
|
||||
# $2 = LONG_MIN
|
||||
# FI
|
||||
#
|
||||
# Treats $1 and $2 as signed values
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
sgn rm rim
|
||||
sgnf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical NEG operation
|
||||
#
|
||||
# $1 = NOT($1) + 1
|
||||
#
|
||||
# Sets CF if $1 == 0; clears it otherwise
|
||||
# Sets OF if $1 == $LONG_MIN; clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
neg rm
|
||||
negf rm
|
||||
|
||||
#
|
||||
# Arithmetical INC operation
|
||||
#
|
||||
# $1 = $1 + 1
|
||||
#
|
||||
# Preserves CF
|
||||
# Sets OF if $1 == $LONG_MAX, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
inc rm
|
||||
incf rm
|
||||
|
||||
#
|
||||
# Arithmetical DEC operation
|
||||
#
|
||||
# $1 = $1 - 1
|
||||
#
|
||||
# Preserves CF
|
||||
# Sets OF if $1 == $LONG_MIN, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
dec rm
|
||||
decf rm
|
||||
|
||||
#
|
||||
# Arithmetical ADD operation
|
||||
#
|
||||
# $1 = $1 + $2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
add rm rim
|
||||
addf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical ADD operation, with carry
|
||||
#
|
||||
# $1 = $1 + $2 + CF
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
adc rm rim
|
||||
adcf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical SUB operation
|
||||
#
|
||||
# $1 = $1 - $2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
sub rm rim
|
||||
subf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned MUL operation
|
||||
#
|
||||
# $1 = LO($1 * $2)
|
||||
#
|
||||
# Sets CF and OF if HI($1 * $2) > 0, clears them otherwise
|
||||
# Preserves ZF and SF
|
||||
#
|
||||
mul rm rim
|
||||
mulf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned DIV operation
|
||||
#
|
||||
# $1 = $1 DIV $2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
div rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned modulo operation (REM)
|
||||
#
|
||||
# $1 = $1 MOD $2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
rem rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned 128-bit MUL operation
|
||||
#
|
||||
# RDX = HI(RAX * $1)
|
||||
# RAX = LO(RAX * $1)
|
||||
#
|
||||
# Sets CF and OF if HI($1 * $2) > 0, clears them otherwise
|
||||
# Preserves ZF and SF
|
||||
#
|
||||
mul2 rim
|
||||
mul2f rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned combined DIV and MOD operations
|
||||
#
|
||||
# RDX = (RAX MOD $1)
|
||||
# RAX = (RAX DIV $1)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
div2 rim
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Comparison instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# TEST Comparison instruction
|
||||
#
|
||||
# $1 AND $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
test rim rim
|
||||
|
||||
#
|
||||
# CMP Comparison instruction
|
||||
#
|
||||
# $1 - $2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
cmp rim rim
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Jump instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Unconditional jump (JMP) instruction
|
||||
#
|
||||
# RIP = $1
|
||||
#
|
||||
j ri
|
||||
jmp ri
|
||||
|
||||
#
|
||||
# RCX-dependent jump (LOOP) instruction
|
||||
#
|
||||
# IF (RCX > 0) THEN
|
||||
# RCX = RCX - 1
|
||||
# RIP = $1
|
||||
# FI
|
||||
#
|
||||
loop ri
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Movement instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Load Effective Address (LEA) instruction
|
||||
#
|
||||
# $1 = ADDR($2)
|
||||
#
|
||||
# For instance:
|
||||
# LEA RAX, [RBX + RCX + 4]
|
||||
# will result in:
|
||||
# RAX = RBX + RCX + 4
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
lea rm m
|
||||
|
||||
#
|
||||
# Movement (MOV) instruction
|
||||
#
|
||||
# $1 = $2
|
||||
#
|
||||
mov rm rim
|
||||
|
||||
#
|
||||
# Movement with zero-extension (MOVZX) instruction
|
||||
#
|
||||
# $1 = ZeroExtend($2)
|
||||
#
|
||||
movzx rm m
|
||||
|
||||
#
|
||||
# Exchange (XCHG) instruction
|
||||
#
|
||||
# $_ = $1
|
||||
# $1 = $2
|
||||
# $2 = $_
|
||||
#
|
||||
xchg rm rim
|
||||
|
||||
#
|
||||
# Compare-and-exchange (CMPXCHG) instruction
|
||||
#
|
||||
# IF ($1 == RAX) THEN
|
||||
# $1 = $2
|
||||
# ZF = 1
|
||||
# ELSE
|
||||
# RAX = $1
|
||||
# ZF = 0
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
#
|
||||
cmpxchg rm rim
|
||||
|
||||
#
|
||||
# Load argument #N (LDARG)
|
||||
#
|
||||
# IF ($2 < 8) THEN
|
||||
# $1 = AX$2
|
||||
# ELSE
|
||||
# $1 = LX($2-8)
|
||||
# FI
|
||||
#
|
||||
# Throws:
|
||||
# #ILL if $2 ≥ 16
|
||||
#
|
||||
ldarg rm rim
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Stack manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Unconditional jump with possible return (CALL)
|
||||
#
|
||||
# PUSH(RIP)
|
||||
# JMP(RIP)
|
||||
#
|
||||
call rim
|
||||
|
||||
#
|
||||
# Return to caller (RET)
|
||||
#
|
||||
# POP(RIP)
|
||||
#
|
||||
ret
|
||||
|
||||
#
|
||||
# Make new stack frame (ENTER)
|
||||
#
|
||||
# PUSH(RBP)
|
||||
# RBP = RSP
|
||||
# RSP = RSP - $1
|
||||
#
|
||||
enter i
|
||||
|
||||
#
|
||||
# Leave stack frame (LEAVE)
|
||||
#
|
||||
# RSP = RBP
|
||||
# POP(RBP)
|
||||
#
|
||||
leave
|
||||
|
||||
#
|
||||
# PUSH value onto stack
|
||||
#
|
||||
# RSP = RSP - 8
|
||||
# *RSP = $1
|
||||
#
|
||||
push rim
|
||||
|
||||
#
|
||||
# POP value from stack
|
||||
#
|
||||
# $1 = *RSP
|
||||
# RSP = RSP + 8
|
||||
#
|
||||
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)
|
||||
#
|
||||
# See dv/DEVAPI
|
||||
#
|
||||
devctl rim rim
|
||||
|
||||
#
|
||||
# Call a device-defined function slot of device (IOCALL)
|
||||
#
|
||||
# See dv/DEVAPI
|
||||
#
|
||||
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
|
||||
|
||||
#
|
||||
# Get timestamp in seconds
|
||||
#
|
||||
time rm
|
||||
|
||||
#
|
||||
# Get timestamp in µseconds
|
||||
#
|
||||
utime rm
|
||||
|
||||
#
|
||||
# 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 #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Clear or set interrupt flag (CLI/STI)
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
cli
|
||||
sti
|
||||
|
||||
#
|
||||
# Clear or set direction flag (CLD/STD)
|
||||
#
|
||||
cld
|
||||
std
|
||||
|
||||
#
|
||||
# Complement, clear or set carry flag (CMC/CLC/STC)
|
||||
#
|
||||
cmc
|
||||
clc
|
||||
stc
|
||||
|
||||
#
|
||||
# Load FLG register (LODF)
|
||||
#
|
||||
# $1 = FLG
|
||||
#
|
||||
lodf rm
|
||||
|
||||
#
|
||||
# Store FLG register - lower byte only (STOFB)
|
||||
#
|
||||
# FLG[7:0] = $1[7:0]
|
||||
#
|
||||
# Note: FLG's lower byte contains CF, OF, ZF, SF, PF and DF
|
||||
#
|
||||
stofb rm
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Byte-wise / bit-wise manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Byte/word/dword swap (xSWAP)
|
||||
#
|
||||
# Change endianness
|
||||
#
|
||||
bswap rm rim
|
||||
wswap rm rim
|
||||
dswap rm rim
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# String manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Store value into string (STOSx)
|
||||
#
|
||||
# [%1] = $2
|
||||
# IF (DF == 0) THEN
|
||||
# %str = %str + sizeof(x)
|
||||
# ELSE
|
||||
# %str = %str - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# When no parameters are given, %str = RDI and $val = RAX
|
||||
# When one parameter is given, %str = RDI and $val = $1
|
||||
# When two parameters are given, %str = $1 and $val = $2
|
||||
#
|
||||
stosb r rim
|
||||
stosw r rim
|
||||
stosl r rim
|
||||
stosq r rim
|
||||
|
||||
#
|
||||
# Load value from string (LODSx)
|
||||
#
|
||||
# $1 = [%2]
|
||||
# IF (DF == 0) THEN
|
||||
# %str = %str + sizeof(x)
|
||||
# ELSE
|
||||
# %str = %str - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
# Sets ZF according to the loaded value
|
||||
#
|
||||
lodsb r r
|
||||
lodsw r r
|
||||
lodsl r r
|
||||
lodsq r r
|
||||
|
||||
#
|
||||
# Scan string for a particular value (SCASx)
|
||||
#
|
||||
# CMP([%1], $2)
|
||||
#
|
||||
# IF ([%1] == 0) THEN
|
||||
# ZF = 1
|
||||
# ELIF (ZF == 0) THEN
|
||||
# IF (DF == 0) THEN
|
||||
# %1 = %1 + sizeof(x)
|
||||
# ELSE
|
||||
# %1 = %1 - sizeof(x)
|
||||
# FI
|
||||
# FI
|
||||
#
|
||||
# Sets CF, OF and SF according to the result of the comparison
|
||||
# Sets ZF according to whether [%1] and $2 are equal, OR if [%1] is null
|
||||
#
|
||||
# Notes:
|
||||
# - Does not move past the value when found
|
||||
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
|
||||
#
|
||||
scasb r rim
|
||||
scasw r rim
|
||||
scasl r rim
|
||||
scasq r rim
|
||||
|
||||
#
|
||||
# Compare bytes in strings (CMPSx)
|
||||
#
|
||||
# CMP([%1], [%2])
|
||||
#
|
||||
# IF (DF == 0) THEN
|
||||
# %1 = %1 + sizeof(x)
|
||||
# %2 = %2 + sizeof(x)
|
||||
# ELSE
|
||||
# %1 = %1 - sizeof(x)
|
||||
# %2 = %2 - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# Sets CF, OF, ZF and SF according to the result of the comparison
|
||||
#
|
||||
# Moves past the compared values in any case!
|
||||
#
|
||||
cmpsb r r
|
||||
cmpsw r r
|
||||
cmpsl r r
|
||||
cmpsq r r
|
||||
|
||||
#
|
||||
# Safe compare bytes in strings (CMPZSx)
|
||||
#
|
||||
# Behaves precisely like CMPSx, except in the following case:
|
||||
# - If both [%1] and [%2] are zero, clears ZF (indicating NOT EQUAL)
|
||||
#
|
||||
# This prevents 'CMPZSx.REP.Z' from looping infinitely when both strings
|
||||
# have the exact same content; this allows for short strcmp's
|
||||
#
|
||||
cmpzsb r r
|
||||
cmpzsw r r
|
||||
cmpzsl r r
|
||||
cmpzsq r r
|
||||
|
||||
#
|
||||
# Move value from string to string (MOVSx)
|
||||
#
|
||||
# [%1] = [%1]
|
||||
# IF (DF == 0) THEN
|
||||
# %1 = %1 + sizeof(x)
|
||||
# %2 = %2 + sizeof(x)
|
||||
# ELSE
|
||||
# %1 = %1 - sizeof(x)
|
||||
# %2 = %2 - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
# Sets ZF according to the moved value
|
||||
#
|
||||
movsb r r
|
||||
movsw r r
|
||||
movsl r r
|
||||
movsq r r
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
include "SUPER"
|
||||
include "TRAP"
|
||||
include "MOV"
|
||||
include "MISC"
|
||||
include "LOGIC"
|
||||
include "ARITH"
|
||||
include "JUMPS"
|
||||
include "STACK"
|
||||
include "FLAGS"
|
||||
include "INOUT"
|
||||
include "DEBUG"
|
||||
include "STRING"
|
||||
|
||||
|
24
vm/in/JUMPS
Normal file
24
vm/in/JUMPS
Normal file
@ -0,0 +1,24 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Jump instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Unconditional jump (JMP) instruction
|
||||
#
|
||||
# RIP = $1
|
||||
#
|
||||
j ri
|
||||
jmp ri
|
||||
|
||||
#
|
||||
# RCX-dependent jump (LOOP) instruction
|
||||
#
|
||||
# IF (RCX > 0) THEN
|
||||
# RCX = RCX - 1
|
||||
# RIP = $1
|
||||
# FI
|
||||
#
|
||||
loop ri
|
65
vm/in/LOGIC
Normal file
65
vm/in/LOGIC
Normal file
@ -0,0 +1,65 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Logical instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# TEST Comparison instruction
|
||||
#
|
||||
# $1 AND $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
test rim rim
|
||||
|
||||
#
|
||||
# Bitwise NOT operation
|
||||
#
|
||||
# $1 = NOT($1)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
not rm
|
||||
|
||||
#
|
||||
# Bitwise OR operation
|
||||
#
|
||||
# $1 = $1 OR $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
or rm rim
|
||||
orf rm rim
|
||||
|
||||
#
|
||||
# Bitwise AND operation
|
||||
#
|
||||
# $1 = $1 AND $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
and rm rim
|
||||
andf rm rim
|
||||
|
||||
#
|
||||
# Bitwise XOR operation
|
||||
#
|
||||
# $1 = $1 XOR $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
xor rm rim
|
||||
xorf rm rim
|
||||
|
||||
# To document
|
||||
shl rm rim
|
||||
shr rm rim
|
||||
shlf rm rim
|
||||
shrf rm rim
|
||||
|
83
vm/in/MISC
Normal file
83
vm/in/MISC
Normal file
@ -0,0 +1,83 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# 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
|
||||
|
||||
#
|
||||
# Pause the CPU for a relatively long time (XPAUSE)
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
xpause
|
||||
|
||||
#
|
||||
# Get timestamp in seconds
|
||||
#
|
||||
time rm
|
||||
|
||||
#
|
||||
# Get timestamp in µseconds
|
||||
#
|
||||
utime rm
|
||||
|
||||
#
|
||||
# CPU Identification Number
|
||||
#
|
||||
# Does nothing (for now)
|
||||
#
|
||||
cpuid
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# 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
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Byte-wise / bit-wise manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Byte/word/dword swap (xSWAP)
|
||||
#
|
||||
# Change endianness
|
||||
#
|
||||
bswap rm rim
|
||||
wswap rm rim
|
||||
dswap rm rim
|
||||
|
82
vm/in/MOV
Normal file
82
vm/in/MOV
Normal file
@ -0,0 +1,82 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Movement instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Load Effective Address (LEA) instruction
|
||||
#
|
||||
# $1 = ADDR($2)
|
||||
#
|
||||
# For instance:
|
||||
# LEA RAX, [RBX + RCX + 4]
|
||||
# will result in:
|
||||
# RAX = RBX + RCX + 4
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
lea rm m
|
||||
|
||||
#
|
||||
# Movement (MOV) instruction
|
||||
#
|
||||
# $1 = $2
|
||||
#
|
||||
mov rm rim
|
||||
|
||||
#
|
||||
# Movement with zero-extension (MOVZX) instruction
|
||||
#
|
||||
# $1 = ZeroExtend($2)
|
||||
#
|
||||
movzx rm m
|
||||
|
||||
#
|
||||
# Exchange (XCHG) instruction
|
||||
#
|
||||
# $_ = $1
|
||||
# $1 = $2
|
||||
# $2 = $_
|
||||
#
|
||||
xchg rm rim
|
||||
|
||||
#
|
||||
# Compare-and-exchange (CMPXCHG) instruction
|
||||
#
|
||||
# IF ($1 == RAX) THEN
|
||||
# $1 = $2
|
||||
# ZF = 1
|
||||
# ELSE
|
||||
# RAX = $1
|
||||
# ZF = 0
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
#
|
||||
cmpxchg rm rim
|
||||
|
||||
#
|
||||
# Load argument #N (LDARG)
|
||||
#
|
||||
# IF ($2 < 8) THEN
|
||||
# $1 = AX$2
|
||||
# ELSE
|
||||
# $1 = LX($2-8)
|
||||
# FI
|
||||
#
|
||||
# Throws:
|
||||
# #ILL if $2 ≥ 16
|
||||
#
|
||||
ldarg rm rim
|
||||
|
||||
#
|
||||
# Get code/data offset (GCO/GCD)
|
||||
#
|
||||
# $1 = CR1 (GCO)
|
||||
# $1 = CR2 (GCD)
|
||||
#
|
||||
gco rm
|
||||
gcd rm
|
||||
|
55
vm/in/STACK
Normal file
55
vm/in/STACK
Normal file
@ -0,0 +1,55 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Stack manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Unconditional jump with possible return (CALL)
|
||||
#
|
||||
# PUSH(RIP)
|
||||
# JMP(RIP)
|
||||
#
|
||||
call rim
|
||||
|
||||
#
|
||||
# Return to caller (RET)
|
||||
#
|
||||
# POP(RIP)
|
||||
#
|
||||
ret
|
||||
|
||||
#
|
||||
# Make new stack frame (ENTER)
|
||||
#
|
||||
# PUSH(RBP)
|
||||
# RBP = RSP
|
||||
# RSP = RSP - $1
|
||||
#
|
||||
enter i
|
||||
|
||||
#
|
||||
# Leave stack frame (LEAVE)
|
||||
#
|
||||
# RSP = RBP
|
||||
# POP(RBP)
|
||||
#
|
||||
leave
|
||||
|
||||
#
|
||||
# PUSH value onto stack
|
||||
#
|
||||
# RSP = RSP - 8
|
||||
# *RSP = $1
|
||||
#
|
||||
push rim
|
||||
|
||||
#
|
||||
# POP value from stack
|
||||
#
|
||||
# $1 = *RSP
|
||||
# RSP = RSP + 8
|
||||
#
|
||||
pop rm
|
||||
|
129
vm/in/STRING
Normal file
129
vm/in/STRING
Normal file
@ -0,0 +1,129 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# String manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Store value into string (STOSx)
|
||||
#
|
||||
# [%1] = $2
|
||||
# IF (DF == 0) THEN
|
||||
# %str = %str + sizeof(x)
|
||||
# ELSE
|
||||
# %str = %str - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# When no parameters are given, %str = RDI and $val = RAX
|
||||
# When one parameter is given, %str = RDI and $val = $1
|
||||
# When two parameters are given, %str = $1 and $val = $2
|
||||
#
|
||||
stosb r rim
|
||||
stosw r rim
|
||||
stosl r rim
|
||||
stosq r rim
|
||||
|
||||
#
|
||||
# Load value from string (LODSx)
|
||||
#
|
||||
# $1 = [%2]
|
||||
# IF (DF == 0) THEN
|
||||
# %str = %str + sizeof(x)
|
||||
# ELSE
|
||||
# %str = %str - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
# Sets ZF according to the loaded value
|
||||
#
|
||||
lodsb r r
|
||||
lodsw r r
|
||||
lodsl r r
|
||||
lodsq r r
|
||||
|
||||
#
|
||||
# Scan string for a particular value (SCASx)
|
||||
#
|
||||
# CMP([%1], $2)
|
||||
#
|
||||
# IF ([%1] == 0) THEN
|
||||
# ZF = 1
|
||||
# ELIF (ZF == 0) THEN
|
||||
# IF (DF == 0) THEN
|
||||
# %1 = %1 + sizeof(x)
|
||||
# ELSE
|
||||
# %1 = %1 - sizeof(x)
|
||||
# FI
|
||||
# FI
|
||||
#
|
||||
# Sets CF, OF and SF according to the result of the comparison
|
||||
# Sets ZF according to whether [%1] and $2 are equal, OR if [%1] is null
|
||||
#
|
||||
# Notes:
|
||||
# - Does not move past the value when found
|
||||
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
|
||||
#
|
||||
scasb r rim
|
||||
scasw r rim
|
||||
scasl r rim
|
||||
scasq r rim
|
||||
|
||||
#
|
||||
# Compare bytes in strings (CMPSx)
|
||||
#
|
||||
# CMP([%1], [%2])
|
||||
#
|
||||
# IF (DF == 0) THEN
|
||||
# %1 = %1 + sizeof(x)
|
||||
# %2 = %2 + sizeof(x)
|
||||
# ELSE
|
||||
# %1 = %1 - sizeof(x)
|
||||
# %2 = %2 - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# Sets CF, OF, ZF and SF according to the result of the comparison
|
||||
#
|
||||
# Moves past the compared values in any case!
|
||||
#
|
||||
cmpsb r r
|
||||
cmpsw r r
|
||||
cmpsl r r
|
||||
cmpsq r r
|
||||
|
||||
#
|
||||
# Safe compare bytes in strings (CMPZSx)
|
||||
#
|
||||
# Behaves precisely like CMPSx, except in the following case:
|
||||
# - If both [%1] and [%2] are zero, clears ZF (indicating NOT EQUAL)
|
||||
#
|
||||
# This prevents 'CMPZSx.REP.Z' from looping infinitely when both strings
|
||||
# have the exact same content; this allows for short strcmp's
|
||||
#
|
||||
cmpzsb r r
|
||||
cmpzsw r r
|
||||
cmpzsl r r
|
||||
cmpzsq r r
|
||||
|
||||
#
|
||||
# Move value from string to string (MOVSx)
|
||||
#
|
||||
# [%1] = [%1]
|
||||
# IF (DF == 0) THEN
|
||||
# %1 = %1 + sizeof(x)
|
||||
# %2 = %2 + sizeof(x)
|
||||
# ELSE
|
||||
# %1 = %1 - sizeof(x)
|
||||
# %2 = %2 - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
# Sets ZF according to the moved value
|
||||
#
|
||||
movsb r r
|
||||
movsw r r
|
||||
movsl r r
|
||||
movsq r r
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
|
37
vm/in/SUPER
Normal file
37
vm/in/SUPER
Normal file
@ -0,0 +1,37 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Supervisor only instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Initiate machine shutdown (STOP)
|
||||
#
|
||||
# THROW #SHT
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
# #ILL if disabled through DV
|
||||
# #SHT otherwise
|
||||
#
|
||||
stop
|
||||
|
||||
#
|
||||
# Halt the processor until next E/I (HLT)
|
||||
#
|
||||
hlt
|
||||
|
||||
#
|
||||
# Call an architecture-reserved function slot of device (DEVCTL)
|
||||
#
|
||||
# See dv/DEVAPI
|
||||
#
|
||||
devctl rim rim
|
||||
|
||||
#
|
||||
# Call a device-defined function slot of device (IOCALL)
|
||||
#
|
||||
# See dv/DEVAPI
|
||||
#
|
||||
iocall rim rim
|
20
vm/in/TRAP
Normal file
20
vm/in/TRAP
Normal file
@ -0,0 +1,20 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# 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
|
7
vm/in/arch_i.c
Normal file
7
vm/in/arch_i.c
Normal file
@ -0,0 +1,7 @@
|
||||
// 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>
|
||||
|
||||
#define _NEED_ARCH_I
|
||||
#include <in/arch_i.h>
|
204
vm/in/arch_i.py
204
vm/in/arch_i.py
@ -5,6 +5,114 @@
|
||||
|
||||
from tempfile import TemporaryFile
|
||||
|
||||
def getflag(s):
|
||||
if s == "r":
|
||||
return "P_REG"
|
||||
|
||||
if s == "i":
|
||||
return "P_IMM"
|
||||
|
||||
if s == "m":
|
||||
return "P_MEM"
|
||||
|
||||
return "__FLAG_ERROR__"
|
||||
|
||||
def doprnt(fp, i, p1, p2):
|
||||
for c1 in p1:
|
||||
for c2 in p2:
|
||||
fp.write("{} {} {}".format(i, c1, c2).strip())
|
||||
fp.write('\n')
|
||||
|
||||
def parse_1(fi, fp):
|
||||
global count
|
||||
|
||||
# "instr ri ri" => "instr r r\ninstr r i\ninstr i r..."
|
||||
# not optimal but will do for now
|
||||
for _, line in enumerate(fi):
|
||||
if line[0] == '#' or line[0] == ' ' or line[0] == '\n':
|
||||
continue
|
||||
|
||||
line = line.strip()
|
||||
|
||||
if line[:8] == "include ":
|
||||
_, fn = line.split(' ', 1)
|
||||
fi2 = open(fn[1:-1])
|
||||
parse_1(fi2, fp)
|
||||
continue
|
||||
|
||||
tok = line.split(' ')
|
||||
|
||||
if len(tok) == 0:
|
||||
continue
|
||||
|
||||
i = tok[0].strip()
|
||||
|
||||
if len(tok) == 1:
|
||||
doprnt(fp, i, ' ', ' ')
|
||||
continue
|
||||
|
||||
if len(tok) == 2:
|
||||
p = tok[1].strip()
|
||||
doprnt(fp, i, p, ' ')
|
||||
continue
|
||||
|
||||
assert(len(tok) == 3)
|
||||
|
||||
p1 = tok[1].strip()
|
||||
p2 = tok[2].strip()
|
||||
|
||||
doprnt(fp, i, p1, p2)
|
||||
|
||||
fi.close()
|
||||
|
||||
def parse_2(fp):
|
||||
global count
|
||||
fp.seek(0)
|
||||
|
||||
for _, line in enumerate(fp):
|
||||
tok = line.strip().split(' ')
|
||||
|
||||
assert(len(tok) > 0)
|
||||
|
||||
deprecated = ''
|
||||
if tok[0][0] == '!':
|
||||
assert(len(tok[0]) > 1)
|
||||
deprecated = '__'
|
||||
tok[0] = tok[0][1:]
|
||||
|
||||
if len(tok) == 1:
|
||||
name = tok[0]
|
||||
p1 = "NOPRM"
|
||||
p2 = "NOPRM"
|
||||
|
||||
elif len(tok) == 2:
|
||||
name = "{}_{}".format(tok[0], tok[1].strip())
|
||||
p1 = getflag(tok[1])
|
||||
p2 = "NOPRM"
|
||||
|
||||
elif len(tok) == 3:
|
||||
name = "{}_{}_{}".format(tok[0], tok[1], tok[2].strip())
|
||||
p1 = getflag(tok[1])
|
||||
p2 = getflag(tok[2])
|
||||
|
||||
else:
|
||||
name = "__TOK_ERROR__"
|
||||
p1 = "__TOK_ERROR__"
|
||||
p2 = "__TOK_ERROR__"
|
||||
|
||||
ls.write("{}{}\n".format(deprecated, name))
|
||||
|
||||
hd.write("#ifdef _NEED_ARCH_I\n")
|
||||
hd.write('{{ "{}{}", "{}{}", {}, {}, i_{} }},\n'\
|
||||
.format(deprecated, tok[0], deprecated, name, p1, p2, tok[0]))
|
||||
hd.write("#else\n")
|
||||
hd.write("#define I_{} {}\n".format(name.upper(), count))
|
||||
hd.write("extern bool i_{}(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);\n"
|
||||
.format(tok[0]))
|
||||
hd.write("#endif\n\n")
|
||||
|
||||
count = count + 1
|
||||
|
||||
fi = open("INSTRS")
|
||||
hd = open("arch_i.h", "w")
|
||||
ls = open("instrs.lst", "w")
|
||||
@ -18,99 +126,8 @@ hd.write("instr_t arch_i[] =\n{\n\n")
|
||||
hd.write("#endif\n")
|
||||
|
||||
fp = TemporaryFile(mode="w+")
|
||||
|
||||
def getflag(s):
|
||||
if s == "r":
|
||||
return "P_REG"
|
||||
|
||||
if s == "i":
|
||||
return "P_IMM"
|
||||
|
||||
if s == "m":
|
||||
return "P_MEM"
|
||||
|
||||
return "__FLAG_ERROR__"
|
||||
|
||||
def doprnt(i, p1, p2):
|
||||
for c1 in p1:
|
||||
for c2 in p2:
|
||||
fp.write("{} {} {}".format(i, c1, c2).strip())
|
||||
fp.write('\n')
|
||||
|
||||
# "instr ri ri" => "instr r r\ninstr r i\ninstr i r..."
|
||||
# not optimal but will do for now
|
||||
for _, line in enumerate(fi):
|
||||
if line[0] == '#' or line[0] == ' ' or line[0] == '\n':
|
||||
continue
|
||||
|
||||
tok = line.strip().split(' ')
|
||||
|
||||
if len(tok) == 0:
|
||||
continue
|
||||
|
||||
i = tok[0].strip()
|
||||
|
||||
if len(tok) == 1:
|
||||
doprnt(i, ' ', ' ')
|
||||
continue
|
||||
|
||||
if len(tok) == 2:
|
||||
p = tok[1].strip()
|
||||
doprnt(i, p, ' ')
|
||||
continue
|
||||
|
||||
assert(len(tok) == 3)
|
||||
|
||||
p1 = tok[1].strip()
|
||||
p2 = tok[2].strip()
|
||||
|
||||
doprnt(i, p1, p2)
|
||||
|
||||
fp.seek(0)
|
||||
|
||||
for _, line in enumerate(fp):
|
||||
tok = line.strip().split(' ')
|
||||
|
||||
assert(len(tok) > 0)
|
||||
|
||||
deprecated = ''
|
||||
if tok[0][0] == '!':
|
||||
assert(len(tok[0]) > 1)
|
||||
deprecated = '__'
|
||||
tok[0] = tok[0][1:]
|
||||
|
||||
if len(tok) == 1:
|
||||
name = tok[0]
|
||||
p1 = "NOPRM"
|
||||
p2 = "NOPRM"
|
||||
|
||||
elif len(tok) == 2:
|
||||
name = "{}_{}".format(tok[0], tok[1].strip())
|
||||
p1 = getflag(tok[1])
|
||||
p2 = "NOPRM"
|
||||
|
||||
elif len(tok) == 3:
|
||||
name = "{}_{}_{}".format(tok[0], tok[1], tok[2].strip())
|
||||
p1 = getflag(tok[1])
|
||||
p2 = getflag(tok[2])
|
||||
|
||||
else:
|
||||
name = "__TOK_ERROR__"
|
||||
p1 = "__TOK_ERROR__"
|
||||
p2 = "__TOK_ERROR__"
|
||||
|
||||
ls.write("{}{}\n".format(deprecated, name))
|
||||
|
||||
hd.write("#ifdef _NEED_ARCH_I\n")
|
||||
hd.write('{{ "{}{}", "{}{}", {}, {}, i_{} }},\n'\
|
||||
.format(deprecated, tok[0], deprecated, name, p1, p2, tok[0]))
|
||||
hd.write("#else\n")
|
||||
hd.write("#define I_{} {}\n".format(name.upper(), count))
|
||||
hd.write("extern bool i_{}(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);\n"
|
||||
.format(tok[0]))
|
||||
hd.write("#endif\n\n")
|
||||
|
||||
count = count + 1
|
||||
parse_1(fi, fp)
|
||||
parse_2(fp)
|
||||
|
||||
hd.write("#ifdef _NEED_ARCH_I\n")
|
||||
hd.write("};\n")
|
||||
@ -120,5 +137,4 @@ hd.write("#endif\n")
|
||||
|
||||
ls.close()
|
||||
hd.close()
|
||||
fi.close()
|
||||
|
||||
|
106
vm/in/devctl.c
106
vm/in/devctl.c
@ -1,106 +0,0 @@
|
||||
// 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/device.h>
|
||||
#include <in/instrs.h>
|
||||
|
||||
//
|
||||
// code common to devctl and iocall
|
||||
//
|
||||
dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
|
||||
{
|
||||
dev_t *dev = devget(ctx, v1);
|
||||
|
||||
if (!dev)
|
||||
rax = -2;
|
||||
|
||||
else if (dev->state == DEVPWOF)
|
||||
rax = -3;
|
||||
|
||||
else if (dev->state == DEVFERR)
|
||||
rax = -4;
|
||||
|
||||
else if (dev->state == DEVPLUG)
|
||||
rax = -5;
|
||||
|
||||
else
|
||||
return dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str)
|
||||
{
|
||||
for (; *str && maxn > 0; str++, addr++, maxn--) {
|
||||
writemem(ctx, *str, addr, 1);
|
||||
}
|
||||
|
||||
writemem(ctx, 0, addr, 1);
|
||||
}
|
||||
|
||||
IMPL_START_2(devctl)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
|
||||
dev_t *dev = devctl_common(ctx, v1, v2);
|
||||
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
switch (v2) {
|
||||
case 0:
|
||||
copystr(ctx, ax0, DEVLEN, dev->type);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
copystr(ctx, ax0, DEVLEN, dev->name);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
copystr(ctx, ax0, DEVLEN, dev->modl);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
copystr(ctx, ax0, DEVLEN, dev->vend);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
rax = dev->major;
|
||||
rdx = dev->minor;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
rax = dev->feats;
|
||||
rdx = dev->revis;
|
||||
break;
|
||||
|
||||
default:
|
||||
rax = -6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(iocall)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
|
||||
long rc;
|
||||
dev_t *dev = devctl_common(ctx, v1, v2);
|
||||
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
if (v2 >= DEVSLOTS)
|
||||
rax = -6;
|
||||
|
||||
else if (dev->fslots[v2] == NULL)
|
||||
rax = -6;
|
||||
|
||||
else {
|
||||
rc = dev->fslots[v2](ctx, dev);
|
||||
if (rc < 0) rax = rc;
|
||||
}
|
||||
}
|
||||
IMPL_END;
|
||||
|
@ -5,6 +5,22 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_0(cli)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
cr0 &= ~IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(sti)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
cr0 |= IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_0(cld)
|
||||
{
|
||||
flg &= ~DF;
|
||||
|
@ -1,90 +0,0 @@
|
||||
// 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 <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <pc/console.h>
|
||||
|
||||
#define _NEED_ARCH_I
|
||||
#include <in/arch_i.h>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_0(nop)
|
||||
{
|
||||
}
|
||||
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;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(rand32)
|
||||
{
|
||||
v1 = (int)random();
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(rand64)
|
||||
{
|
||||
v1 = (random() << 32) | (int)random();
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(time)
|
||||
{
|
||||
v1 = time(NULL);
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(utime)
|
||||
{
|
||||
struct timeval time;
|
||||
gettimeofday(&time, NULL);
|
||||
v1 = (time.tv_sec * 1000) + (time.tv_usec / 1000);
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_0(clr)
|
||||
{
|
||||
rax = rbx = rcx = rdx = 0;
|
||||
rsx = rbi = rdi = rsi = 0;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cla)
|
||||
{
|
||||
ax0 = ax1 = ax2 = ax3 = 0;
|
||||
ax4 = ax5 = ax6 = ax7 = 0;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
65
vm/in/misc.c
65
vm/in/misc.c
@ -2,6 +2,71 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include <in/instrs.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_0(nop)
|
||||
{
|
||||
}
|
||||
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;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(time)
|
||||
{
|
||||
v1 = time(NULL);
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(utime)
|
||||
{
|
||||
struct timeval time;
|
||||
gettimeofday(&time, NULL);
|
||||
v1 = (time.tv_sec * 1000) + (time.tv_usec / 1000);
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_0(clr)
|
||||
{
|
||||
rax = rbx = rcx = rdx = 0;
|
||||
rsx = rbi = rdi = rsi = 0;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cla)
|
||||
{
|
||||
ax0 = ax1 = ax2 = ax3 = 0;
|
||||
ax4 = ax5 = ax6 = ax7 = 0;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
109
vm/in/super.c
109
vm/in/super.c
@ -2,9 +2,17 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pc/device.h>
|
||||
#include <in/instrs.h>
|
||||
#include <pc/console.h>
|
||||
|
||||
IMPL_START_0(stop)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
_except(ctx, E_SHT, "STOP INSTR");
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(hlt)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
@ -21,24 +29,103 @@ IMPL_START_0(hlt)
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cli)
|
||||
//
|
||||
// code common to devctl and iocall
|
||||
//
|
||||
dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
|
||||
{
|
||||
dev_t *dev = devget(ctx, v1);
|
||||
|
||||
if (!dev)
|
||||
rax = -2;
|
||||
|
||||
else if (dev->state == DEVPWOF)
|
||||
rax = -3;
|
||||
|
||||
else if (dev->state == DEVFERR)
|
||||
rax = -4;
|
||||
|
||||
else if (dev->state == DEVPLUG)
|
||||
rax = -5;
|
||||
|
||||
else
|
||||
return dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str)
|
||||
{
|
||||
for (; *str && maxn > 0; str++, addr++, maxn--) {
|
||||
writemem(ctx, *str, addr, 1);
|
||||
}
|
||||
|
||||
writemem(ctx, 0, addr, 1);
|
||||
}
|
||||
|
||||
IMPL_START_2(devctl)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
cr0 &= ~IF;
|
||||
|
||||
dev_t *dev = devctl_common(ctx, v1, v2);
|
||||
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
switch (v2) {
|
||||
case 0:
|
||||
copystr(ctx, ax0, DEVLEN, dev->type);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
copystr(ctx, ax0, DEVLEN, dev->name);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
copystr(ctx, ax0, DEVLEN, dev->modl);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
copystr(ctx, ax0, DEVLEN, dev->vend);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
rax = dev->major;
|
||||
rdx = dev->minor;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
rax = dev->feats;
|
||||
rdx = dev->revis;
|
||||
break;
|
||||
|
||||
default:
|
||||
rax = -6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(sti)
|
||||
IMPL_START_2(iocall)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
cr0 |= IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(stop)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
_except(ctx, E_SHT, "STOP INSTR");
|
||||
|
||||
long rc;
|
||||
dev_t *dev = devctl_common(ctx, v1, v2);
|
||||
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
if (v2 >= DEVSLOTS)
|
||||
rax = -6;
|
||||
|
||||
else if (dev->fslots[v2] == NULL)
|
||||
rax = -6;
|
||||
|
||||
else {
|
||||
rc = dev->fslots[v2](ctx, dev);
|
||||
if (rc < 0) rax = rc;
|
||||
}
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#include <in/instrs.h>
|
||||
|
||||
static volatile long *prev_stk;
|
||||
|
||||
IMPL_START_1(trap)
|
||||
{
|
||||
if (v1 > 255)
|
||||
|
@ -3,8 +3,15 @@
|
||||
|
||||
#include <pc/console.h>
|
||||
|
||||
#define CONSOLE_WIDTH 80
|
||||
#define CONSOLE_HEIGHT 25
|
||||
#ifndef _LARGE_SCREEN
|
||||
# define CONSOLE_WIDTH 80
|
||||
# define CONSOLE_HEIGHT 25
|
||||
# define CONSOLE_FONT_SIZE 16
|
||||
#else
|
||||
# define CONSOLE_WIDTH 160
|
||||
# define CONSOLE_HEIGHT 50
|
||||
# define CONSOLE_FONT_SIZE 32
|
||||
#endif
|
||||
|
||||
#define SCREEN_WIDTH (9 * CONSOLE_WIDTH)
|
||||
#define SCREEN_HEIGHT (16 * CONSOLE_HEIGHT)
|
||||
@ -43,7 +50,7 @@ void console_init(ctx_t *ctx)
|
||||
TTF_Init();
|
||||
|
||||
scr_font = TTF_OpenFont
|
||||
("fn/console_font.ttf", 16);
|
||||
("fn/console_font.ttf", CONSOLE_FONT_SIZE);
|
||||
|
||||
if (scr_font == NULL)
|
||||
{
|
||||
|
@ -28,7 +28,11 @@ void dump_instr(ctx_t *ctx,
|
||||
uint cond,
|
||||
ulong pc)
|
||||
{
|
||||
/*
|
||||
trace("%03lu 0x%lX:\t", ctx->ninstrs, pc);
|
||||
*/
|
||||
|
||||
trace("0x%lX:\t", pc);
|
||||
|
||||
if (lock)
|
||||
trace("lock");
|
||||
|
@ -10,7 +10,6 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
||||
va_list ap;
|
||||
ulong handler;
|
||||
uint code = _code;
|
||||
volatile char ch;
|
||||
|
||||
ulong orig_frame;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user