Verified Commit 2be6db84 authored by GovanifY's avatar GovanifY
Browse files

bunch of rework and swap to eclipse for more advanced work

parent 56446d98
......@@ -9,3 +9,4 @@
.gdb_history
*.zip
*.kate-swp
bin/*
#Sun Dec 22 10:20:50 CET 2019
gradle.version=5.0
// Builds a Ghidra Extension for a given Ghidra installation.
//
// An absolute path to the Ghidra installation directory must be supplied either by setting the
// GHIDRA_INSTALL_DIR environment variable or Gradle project property:
//
// > export GHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
// > gradle
//
// or
//
// > gradle -PGHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
//
// Gradle should be invoked from the directory of the project to build. Please see the
// application.gradle.version property in <GHIDRA_INSTALL_DIR>/Ghidra/application.properties
// for the correction version of Gradle to use for the Ghidra installation you specify.
//----------------------START "DO NOT MODIFY" SECTION------------------------------
def ghidraInstallDir
if (System.env.GHIDRA_INSTALL_DIR) {
ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR
}
else if (project.hasProperty("GHIDRA_INSTALL_DIR")) {
ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR")
}
if (ghidraInstallDir) {
apply from: new File(ghidraInstallDir).getCanonicalPath() + "/support/buildExtension.gradle"
}
else {
throw new GradleException("GHIDRA_INSTALL_DIR is not defined!")
}
//----------------------END "DO NOT MODIFY" SECTION-------------------------------
The "data" directory is intended to hold data files that will be used by this module and will
not end up in the .jar file, but will be present in the zip or tar file. Typically, data
files are placed here rather than in the resources directory if the user may need to edit them.
An optional data/languages directory can exist for the purpose of containing various Sleigh language
specification files and importer opinion files.
The data/buildLanguage.xml is used for building the contents of the data/languages directory.
The skel language definition has been commented-out within the skel.ldefs file so that the
skeleton language does not show-up within Ghidra.
See the Sleigh language documentation (docs/languages/index.html) for details Sleigh language
specification syntax.
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
+ Compile sleigh languages within this module.
+ Sleigh compiler options are read from the sleighArgs.txt file.
+ Eclipse: right-click on this file and choose menu item "Run As->Ant Build"
-->
<project name="privateBuildDeveloper" default="sleighCompile">
<property name="sleigh.compile.class" value="ghidra.pcodeCPort.slgh_compile.SleighCompile"/>
<!--Import optional ant properties. GhidraDev Eclipse plugin produces this so this file can find the Ghidra installation-->
<import file="../.antProperties.xml" optional="false" />
<target name="sleighCompile">
<!-- If language module is detached from installation, get Ghidra installation directory path from imported properties -->
<property name="framework.path" value="${ghidra.install.dir}/Ghidra/Framework"/>
<path id="sleigh.class.path">
<fileset dir="${framework.path}/SoftwareModeling/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${framework.path}/Generic/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${framework.path}/Utility/lib">
<include name="*.jar"/>
</fileset>
</path>
<available classname="${sleigh.compile.class}" classpathref="sleigh.class.path" property="sleigh.compile.exists"/>
<fail unless="sleigh.compile.exists" />
<java classname="${sleigh.compile.class}"
classpathref="sleigh.class.path"
fork="true"
failonerror="true">
<jvmarg value="-Xmx2048M"/>
<arg value="-i"/>
<arg value="sleighArgs.txt"/>
<arg value="-a"/>
<arg value="./languages"/>
</java>
</target>
</project>
define space ram type=ram_space size=4 wordsize=1 default;
define space register type=register_space size=4;
# this is obviously wrong and will need to be edited when i understand how
# internal regs are used besides stack
define register offset=0 size=4 [
r0 r1 r2 r3 r4 r5 r6
r7 r8 pc sp ra broken
];
define token instr(16)
opcode = (0, 3)
ssub_opc = (6, 15)
sub_opc = (4, 5)
iarg = (14, 15);
define token instr_ext(32)
opcode_ext = (0, 3)
sub_opc_ext = (4, 5)
opesub = (6, 7)
_opesub = (6, 7)
rn = (6, 7)
ope3 = (6, 15)
full_ext = (0, 31)
full_rel = (0, 31) signed
# the label thingy
ope2 = (16, 31)
_ope2 = (16, 31)
ope2s = (16, 31) signed;
# relocated labels
LABEL8: reloc is ope2s [ reloc = inst_start+(ope2s*2)+4; ] { export *:4 reloc; }
LABEL02: reloc is ope2s [ reloc = 0x10+(ope2s*2); ] { export *:4 reloc; }
#LABELV: reloc is full_rel [ reloc = 0x10+(full_rel*2); ] { export *:4 reloc; }
NOT_LABEL03: reloc is ope2s [ reloc = 0x10+(ope2s*2); ] { tmp:4 = reloc:4; export tmp; }
#CLABEL: reloc is full_ext [ reloc = 0x10+(full_ext*2); ] { export *:4 reloc; }
# if i'm not mistaken 0x1da4d8 1 and 2 uses two regs
# one of them or more is a status reg so i'll have to double check how it's used
attach variables [ rn ] [ r0 r1 r2 r3 ];
# exit values
attach values [ iarg ] [ 1 2 _ _ ];
define pcodeop system_call;
define pcodeop fmod;
define pcodeop exit;
define pcodeop cos;
define pcodeop sin;
define pcodeop radians_to_degrees;
define pcodeop degrees_to_radians;
macro push(v) {
*[ram]:4 sp = v;
sp = sp + 4;
}
macro pop(v) {
sp = sp - 4;
v = *[ram]:4 sp;
}
macro to_address(v) {
if(v!=0) goto <address>;
v=0;
goto <end>;
<address>
v=0x10+(v*2);
<end>
}
define space ram type=ram_space size=4 wordsize=1 default;
define space register type=register_space size=4;
# this is obviously wrong and will need to be edited when i understand how
# internal regs are used besides stack
define register offset=0 size=4 [
r0 r1 r2 r3 r4 r5 r6
r7 r8 pc sp ra broken
];
define token instr(16)
opcode = (0, 3)
ssub_opc = (6, 15)
sub_opc = (4, 5)
iarg = (14, 15);
define token instr_ext(32)
opcode_ext = (0, 3)
sub_opc_ext = (4, 5)
opesub = (6, 7)
rn = (6, 7)
ope3 = (6, 15)
full_ext = (0, 31)
# the label thingy
ope2 = (16, 31)
ope2s = (16, 31) signed;
# relocated labels
LABEL8: reloc is ope2s [ reloc = inst_start+(ope2s*2)+4; ] { export *:4 reloc; }
LABEL02: reloc is ope2s [ reloc = 0x10+(ope2s*2); ] { export *:4 reloc; }
# if i'm not mistaken 0x1da4d8 1 and 2 uses two regs
# one of them or more is a status reg so i'll have to double check how it's used
attach variables [ rn ] [ _ r0 r1 _ ];
# exit values
attach values [ iarg ] [ 1 2 _ _ ];
define pcodeop system_call;
define pcodeop fmod;
define pcodeop exit;
define pcodeop cos;
define pcodeop sin;
define pcodeop radians_to_degrees;
define pcodeop degrees_to_radians;
macro push(v) {
*[ram]:4 sp = v;
sp = sp + 4;
}
macro pop(v) {
sp = sp - 4;
v = *[ram]:4 sp;
}
#
#
# Instructions
......@@ -67,24 +9,33 @@ macro pop(v) {
# 0x1 =========
# standard push
:push full_ext is opcode=0 & ( sub_opc=1 | sub_opc=0 ) ; full_ext {
# so this is how the game does it, it pushes a value, normal stuff. THE. THING.
# IS. it can sometime push an address too, that a syscall relocates. so we're
# going to have to be hacky to get the entire file to be analyzed. sad day.
# ssub_opc is always equal 0, we just define it in a more specific fashion to
# prefer push.v over _push.v, which is dynamically created by the analyzer
:push.v full_ext is opcode=0 & ( sub_opc=1 | sub_opc=0 ) ; full_ext {
push(full_ext:4);
}
#:pushc CLABEL is opcode=0 & ( sub_opc=1 | sub_opc=0 ) ; CLABEL & full_ext {
# push(full_ext:4);
#}
#push and add
:push2_unk0 is opcode_ext=0 & sub_opc_ext=2 & opesub=0 {
}
# push and add to pointer
:pushap rn, ope2 is opcode_ext=0 & sub_opc_ext=2 & opesub=1 & ope2 & rn {
:push.ap rn, ope2 is opcode_ext=0 & sub_opc_ext=2 & opesub=1 & ope2 & rn {
}
:push2_unk2 is opcode_ext=0 & sub_opc_ext=2 & opesub=2 {
}
:push LABEL02 is opcode_ext=0 & sub_opc_ext=2 & opesub=3 & LABEL02 {
# this is wrong! it pushes the pointer, not the data
:push.l LABEL02 is opcode_ext=0 & sub_opc_ext=2 & opesub=3 & LABEL02 {
push(LABEL02:4);
}
......@@ -93,30 +44,52 @@ macro pop(v) {
}
#push and add
:pusha rn, ope2 is opcode_ext=0 & sub_opc_ext=3 & opesub=1 & ope2 & rn {
:push.a rn, ope2 is opcode_ext=0 & sub_opc_ext=3 & opesub=1 & ope2 & rn {
}
#push and add
:push3_unk2 is opcode_ext=0 & sub_opc_ext=3 & opesub=2 {
}
#push and add
:push3_unk3 is opcode_ext=0 & sub_opc_ext=3 & opesub=3 {
# never used in practice... push pointer as data and not label
:push.ln NOT_LABEL03 is opcode_ext=0 & sub_opc_ext=3 & opesub=3 & NOT_LABEL03 {
push(NOT_LABEL03);
}
# 0x1 =========
# sometimes it has arguments, to check!
:pop is opcode_ext=1 {
# this is a pop_at!!!!!
:popat_unk0 is opcode_ext=1 & ope3=0 & ope2 & rn {
}
:popat rn, ope2 is opcode_ext=1 & ope3=1 & ope2 & rn {
}
:popat_unk2 is opcode_ext=1 & ope3=2 & ope2 & rn {
}
# no shit this isn't used in practice
:popat LABEL02 is opcode_ext=1 & ope3=3 & LABEL02 {
push(LABEL02:4);
}
:unk2 is opcode_ext=2 ; opcode{
:unk2_unk0 is opcode_ext=2 & ope3=0; opcode{
}
:unk2_unk1 is opcode_ext=2 & ope3=1; opcode{
}
:unk2_unk2 is opcode_ext=2 & ope3=2; opcode{
}
:unk2_unk3 is opcode_ext=2 & ope3=3; opcode{
}
# push and add to stack
:pushas ope2 is opcode_ext=3 & ope2{
:push.as ope2 is opcode_ext=3 & ope2{
local tmp:4 = sp;
pop(tmp);
tmp=tmp+ope2;
......@@ -486,11 +459,11 @@ macro pop(v) {
# push cached -> push last cached pushed element to stack
# don't ask me, this entire ISA is cursed
:pushca is opcode=9 & ssub_opc=3{
:push.ca is opcode=9 & ssub_opc=3{
}
# push copy -> push last pushed element to stack
:pushc is opcode=9 & ssub_opc=5{
:push.c is opcode=9 & ssub_opc=5{
}
# sinus; arg in radians
......@@ -531,7 +504,20 @@ macro pop(v) {
# 0x9 =========
#syscall
#:syscall opesub,ope2 is opcode_ext=0xA & opesub & ope2 {
# if (opesub:4==1) goto <table1>;
# <table1>
# if (ope2:4==6) goto <_syscall1_6>;
# # unknown args or no changes necessary
# system_call(opesub:4,ope2:4);
# goto <done>;
# <_syscall1_6>
# syscall1_6();
# goto <done>;
# <done>
#}
:syscall opesub,ope2 is opcode_ext=0xA & opesub & ope2 {
system_call(opesub:4,ope2:4);
}
......
define endian=little;
define alignment=2;
@include "base.sinc"
@include "syscalls.sinc"
@include "kh2ai.sinc"
define pcodeop system_call1_6;
macro syscall1_6() {
local tmp:4 = sp;
pop(tmp);
local tmp2:4 = sp;
pop(tmp2);
local tmp3:4 = sp;
pop(tmp3);
local tmp4:4 = sp;
pop(tmp4);
local tmp5:4 = sp;
pop(tmp5);
local tmp6:4 = sp;
pop(tmp6);
local tmp7:4 = sp;
pop(tmp7);
local tmp8:4 = sp;
pop(tmp8);
local tmp9:4 = sp;
pop(tmp9);
local tmp10:4 = sp;
pop(tmp10);
to_address(tmp2);
to_address(tmp3);
to_address(tmp4);
to_address(tmp5);
to_address(tmp6);
to_address(tmp7);
to_address(tmp8);
to_address(tmp9);
to_address(tmp10);
system_call1_6(tmp, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10);
}
......@@ -57,6 +57,9 @@
}
\newcommand{\ISA}[7]{
\StrLen{#4}[\exclen]
\StrLen{#6}[\notelen]
\section{\huge #1}
\Lineless \\
\textbf{Operation Code} \\ \\
......@@ -65,12 +68,16 @@
\hspace*{0.5cm} #2 \\ \\
\textbf{Description} \\
\hspace*{0.5cm} #3 \\ \\
\ifthenelse{\equal{\exclen}{0}}{}{
\textbf{Exceptions} \\
\hspace*{0.5cm} #4 \\ \\
}
\textbf{Operations} \\
\hspace*{0.5cm} #5 \\ \\
\ifthenelse{\equal{notelen}{0}}{}{
\textbf{Programming notes} \\
\hspace*{0.5cm} #6 \\ \\
}
\newpage
}
......@@ -129,6 +136,13 @@
\Main{Kh2Ai ISA}{\version}
Blabla
It is also worthy to note that some operations that otherwise do the same thing
are given a different mnemonic depending on the context to be easier to write an
assembler. An example of this can be seen in the PUSH.V and PUSH.L operations,
which, while they both push a value to the stack, one of them is 48bits long and
pushes a raw value while the other is 32bits long and does a relocation on the
encoded address before pushing it, making the different naming needed.
\Chapter{Notational Convention}
......@@ -148,101 +162,116 @@
\ISA{POP: pop}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{CFTI: Convert Float To Int}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{CFTI: Convert Float To Int}{CFTI}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{NEG: convert to NEGative signed number}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{NEG: convert to NEGative signed number}{NEG}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{INV: INVert an unsigned value}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{INV: INVert an unsigned value}{INV}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{EQZ: conditional is EQual Zero}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{EQZ: conditional is EQual Zero}{EQZ}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{ABS: convert to ABSolute value}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{ABS: convert to ABSolute value}{ABS}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{MSB: return Most Significant Bit}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{MSB: return Most Significant Bit}{MSB}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{INFO: conditional INFerior to One}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{INFO: conditional INFerior to One}{INFO}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{NEQZ: conditional Not Equal to Zero}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{NEQZ: conditional Not Equal to Zero}{NEQZ}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{MSB: return Most Significant Bit Inverted}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{MSBI: return Most Significant Bit Inverted}{MSBI}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{IPOS: Conditional Is POSitive}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{IPOS: Conditional Is POSitive}{IPOS}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{CITF: Convert Int To Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{CITF: Convert Int To Float}{CITF}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{NEGF: convert to NEGative Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{NEGF: convert to NEGative Float}{NEGF}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{ABS: convert to ABSolute Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{ABS: convert to ABSolute Float}{ABS}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{INFZF: Conditional INFerior to Zero Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{INFZF: Conditional INFerior to Zero Float}{INFZF}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{INFOEZF: Conditional INFerior Or Equal to Zero Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{INFOEZF: Conditional INFerior Or Equal to Zero Float}{INFOEZF}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{EQZF: conditional is EQual Zero Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{EQZF: conditional is EQual Zero Float}{EQZF}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{NEQZF: conditional Not Equal to Zero Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{NEQZF: conditional Not Equal to Zero Float}{NEQZF}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{SUPOEZF: conditional SUPerior Or Equal to Zero Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{SUPOEZF: conditional SUPerior Or Equal to Zero Float}{SUPOEZF}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{SUPZF: conditional SUPerior to Zero Float}{b}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{SUPZF: conditional SUPerior to Zero Float}{SUPZF}{c}{d}{e}{f}{01000000010010010000111111010000}
\ISA{ADD: ADDition}{b}{c}{d}{e}{f}{11000010000000001}
\ISA{ADD: ADDition}{ADD}{c}{d}{e}{f}{11000010000000001}
\ISA{SUB: SUBstraction}{b}{c}{d}{e}{f}{11000010000000001}
\ISA{SUB: SUBstraction}{SUB}{c}{d}{e}{f}{11000010000000001}
\ISA{MUL: MULtiplication}{b}{c}{d}{e}{f}{11000010000000010}
\ISA{MUL: MULtiplication}{MUL}{c}{d}{e}{f}{11000010000000010}
\ISA{DIV: DIVision}{b}{c}{d}{e}{f}{11000010000000011}
\ISA{DIV: DIVision}{DIV}{c}{d}{e}{f}{11000010000000011}
\ISA{MOD: MODulo}{b}{c}{d}{e}{f}{11000010000000100}
\ISA{MOD: MODulo}{MOD}{c}{d}{e}{f}{11000010000000100}
\ISA{AND: logical AND}{b}{c}{d}{e}{f}{11000010000000101}
\ISA{AND: logical AND}{AND}{c}{d}{e}{f}{11000010000000101}
\ISA{OR: logical OR}{b}{c}{d}{e}{f}{11000010000000110}
\ISA{OR: logical OR}{OR}{c}{d}{e}{f}{11000010000000110}
\ISA{XOR: logical eXclusive OR}{b}{c}{d}{e}{f}{11000010000000111}
\ISA{XOR: logical eXclusive OR}{XOR}{c}{d}{e}{f}{11000010000000111}
\ISA{SLL: Shift Logical Left}{b}{c}{d}{e}{f}{11000010000001000}
\ISA{SLL: Shift Logical Left}{SLL}{c}{d}{e}{f}{11000010000001000}
\ISA{SRA: Shift Right Arithmetic}{b}{c}{d}{e}{f}{11000010000001001}
\ISA{SRA: Shift Right Arithmetic}{SRA}{c}{d}{e}{f}{11000010000001001}
\ISA{NEQZV: conditional Not EQual to Zero with stack Values}{b}{c}{d}{e}{f}{1100001000001010}
\ISA{NEQZV: conditional Not EQual to Zero with stack Values}{NEQZV}{c}{d}{e}{f}{1100001000001010}
\ISA{EQZV: conditional EQual to Zero with stack Values}{b}{c}{d}{e}{f}{11000010000001011}
\ISA{EQZV: conditional EQual to Zero with stack Values}{EQZV}{c}{d}{e}{f}{11000010000001011}
\ISA{ADDF: ADDition with Float values}{b}{c}{d}{e}{f}{11000010000000000}
\ISA{ADDF: ADDition with Float values}{ADDF}{Retrieves the last 2 values pushed on
to the stack and apply an addition onto them, pushing back the result to the
stack.}{d}{e}{This function exclusively deals with floating numbers}{11000010000000000}
\ISA{SUBF: SUBstraction with Float values}{b}{c}{d}{e}{f}{11000010000000001}
\ISA{SUBF: SUBstraction with Float values}{SUBF}{Retrieves the last 2 values pushed on
to the stack and apply a substraction onto them, pushing back the result to the
stack.}{}{}{This function exclusively deals with floating numbers}{11000010000000001}
\ISA{MULF: MULtiplication with Float values}{b}{c}{d}{e}{f}{11000010000000010}
\ISA{MULF: MULtiplication with Float values}{MULF}{Retrieves the last 2 values pushed on
to the stack and apply a multiplication onto them, pushing back the result to the
stack.}{}{}{This function exclusively deals with floating numbers}{11000010000000010}
\ISA{DIVF: DIVision with Float values}{b}{c}{d}{e}{f}{11000010000000011}
\ISA{DIVF: DIVision with Float values}{DIVF}{Retrieves the last 2 values pushed on
to the stack and apply a division onto them, pushing back the result to the
stack.}{}{}{This function exclusively deals with floating numbers}{11000010000000011}
\ISA{MODF: MODulo with Float values}{b}{c}{d}{e}{f}{11000010000000100}
\ISA{MODF: MODulo with Float values}{MODF}{Retrieves the last 2 values pushed on
to the stack and apply a modulo onto them, pushing back the result to the
stack.}{}{}{This function exclusively deals with floating numbers}{11000010000000100}
\ISA{JMP: JuMP}{b}{c}{d}{e}{f}{TODO}
\ISA{EXIT: EXIT}{r=exit value}{c}{d}{e}{f}{100100000000000r}
\ISA{EXIT: EXIT}{EXIT ri}{Completely stops the execution flow of the AI Parser
with return code ri}{}{}{}{100100000000000r}
% bitfields below are all verified
\ISA{RET: RETurn}{b}{c}{d}{e}{f}{1000100100000000}
\ISA{RET: RETurn}{RET}{Stops the execution flow and return back to the last
saved function call}{}{}{}{1000100100000000}
\ISA{PUSHCA: PUSH CAched value}{b}{c}{d}{e}{f}{1100100100000000}
\ISA{PUSH.CA: PUSH CAched value}{PUSHCA}{c}{d}{e}{f}{1100100100000000}
\ISA{PUSHC: PUSH Copy}{b}{c}{d}{e}{f}{0100100100000001}
\ISA{PUSH.C: PUSH Copy}{PUSHC}{c}{d}{e}{f}{0100100100000001}
\ISA{SIN: SINus}{b}{c}{d}{e}{f}{1000100100000001}
\ISA{SIN: SINus}{SIN}{Retrieves the latest value pushed to the stack and apply a
sinus onto it, pushing it to the stack}{}{}{Radians are used as input.
Radians used are modulo $[\pi-2\pi]$}{1000100100000001}
\ISA{COS: COSinus}{Retrieves the latest value pushed to the stack and apply a
cosinus onto it, pushing it to the stack}{None}{d}{e}{Radians are used as input.
Radians used are modulo pi-2pi}{1100100100000001}
\ISA{COS: COSinus}{COS}{Retrieves the latest value pushed to the stack and apply a
cosinus onto it, pushing it to the stack}{}{}{Radians are used as input.
Radians used are modulo $[\pi-2\pi]$}{1100100100000001}
\ISA{DEGR: DEGrees to Radians}{Retrieves the last element pushed to the stack
and converts it to radians, pushing it to the stack}{None}{d}{e}{Radians used
are modulo pi-2pi}{0000100100000010}