Skip to content

Commit

Permalink
Updated docs, Readme and corrections
Browse files Browse the repository at this point in the history
  • Loading branch information
JnnDrc committed Jul 23, 2024
1 parent bfb8304 commit 1cc8977
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 32 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
CC = gcc



lc3-vm: src\vm.c
$(CC) $< -o $@

lc3-vm_gdb: src\vm.c
$(CC) $< -o $@ -g
.PHONY: gdb
gdb: src\vm.c
$(CC) $< -o lc3-vm_gdb -g
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,29 @@ this was made/inspired in these articles
[by Andrei Ciobanu](https://www.andreinc.net/2021/12/01/writing-a-simple-vm-in-less-than-125-lines-of-c#virtual-machines)
[by Justin Meiners & Ryan Pendleton](https://www.jmeiners.com/lc3-vm/)

There's a small manual for this VM in the VMLC3.md and VMLC3-PT.md
and some example programs in programs folder.
You can make your own programs in a .txt file and use hexc to compile this them
to machine code, see HEXC.md.
## Compile

Just type `make` in console and input.
if you want to use gdb, use `make gdb`

## Run

To run a program in VM type `lc3-vm [program] [--optional_params]`
the program is a bin file, generally .o/.obj.
There are some example programs in _programs_ or
You can use hexc to compile your own programs.

The optional params are listed in the VM's manual
or in typing `lc3-vm --help`.

## Manuals

There's some manuals in the docs folder

* [VMLC3.md](docs\VMLC3.md) : VM's manual in english
* [VMLC3-PT.md](docs\VMLC3-PT.md) : VM's manual in portuguese
* [HEXC.md](docs\HEXC.md) : hexc's manual (in english)

## Known issues

none _currently_
5 changes: 2 additions & 3 deletions HEXC.md → docs/HEXC.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This small program compiles a plain text file with
hex numbers, to a raw file with these hex values

## use
## Use

for use it you just need a plain text(or any file you want)
with ASCII character representing hex values, this input
Expand All @@ -15,8 +15,6 @@ Expected argument set : hexc \[path_to_input\](OPTIONAL\)\[path_to_output\]
if the output file is not specified, the output will be
\[input_name_without_extension.o\]

`OBS: the max hex value supported is 0xFFFF`

## Syntax

the syntax for the compiler has only two things,s
Expand All @@ -37,6 +35,7 @@ EE3A
```

`OBS: the max size of a line is 256`
`OBS: the max hex value supported is 0xFFFF`

## Example

Expand Down
61 changes: 61 additions & 0 deletions VMLC3-PT.md → docs/VMLC3-PT.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,64 @@ há 10 sub-rotinas para TRPVECT:
<td>0x7</td>
</tr>
</table>

## VM Features

### Special params

Você pode especificar alguns parâmetros
especias para a VM, os parâmetros são
digitados depois do programa.
`lc3-vm [program] [--params]...`

#### --help

Este parâmetro é especial, é diferente dos
outros parâmetros, não altera nada na
execução da VM, não executa nem mesmo
um programa, --help´é digitado no lugar
do programa e imprime uma pequena descrição
de todos os parâmetros especiais cobertos
nesta seção.

`lc3-vm --help`

#### --runoff

Este parâmetro define o deslocamento do valor inicial do PC.
O valor inicial do PC é 0x3000 + runoff(0x), por padrão runoff
é zero, este parâmetro o altera.

`lc3-vm program.o --runoff A1`
isso altera o valor inicial do PC
para 0x30A1

#### --loadoff

Este parâmetro define o deslocamento
da origem de carregamento do programa.
Os programas são escritos começando em
0x3000 + loadoff(0x), por padrão loadoff é zero,
este parâmetro o altera.

`lc3-vm program.o --loadoff FF`
isso altera a origem do
carregamento do programa
para 0x30FF

! AVISO ! : o runoff não muda com o loadoff, preste atenção onde
seu programa começa

#### --memrep

Este parâmetro cria dois
logs da memória, um antes da
execução do programa e outro
após a execução do programa.

`lc3-vm program.o --memrep`
isso gerará estes dois arquivos
.\\
| lc3-vm.exe
| memory\_reports\_[DAY-MONTH-YEAR]\_[HOUR-MIN-SEC]\_final.log
| memory\_reports\_[DAY-MONTH-YEAR]\_[HOUR-MIN-SEC]\_init.log
56 changes: 56 additions & 0 deletions VMLC3.md → docs/VMLC3.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,3 +302,59 @@ there is 10 subroutines for TRPVECT:
<td>0x7</td>
</tr>
</table>

## VM Features

### Special params

You can specify some special params
to the VM, the params are typed
after the program. `lc3-vm [program] [--params]...`

#### --help

This param is _special_, it's different from
the other params, it doesn't changes anything in
the VM run, it doesn't even runs a programs, --help
is typed in the place of the program and it prints
a little description of all special param covered in
this section.

`lc3-vm --help`

#### --runoff

This param set the offset of the PC start value.
The initial value of PC 0x3000 + runoff(0x), by default runoff
is zero, this params changes it.

`lc3-vm program.o --runoff A1`
this changes the start PC value
for 0x30A1

#### --loadoff

This param set the offset of the program loading
origin. The programs are written starting in
0x3000 + loadoff(0x), by default loadoff is zero,
this param changes it.

`lc3-vm program.o --loadoff FF`
this changes the load program origin
to 0x30FF

! WARNING ! : the runoff doesn't changes with loadoff, pay attention where
your program begins

#### --memrep

This param prints creates two
logs of the memory, one before the
program run, and another after the program run.

`lc3-vm program.o --memrep`
this will generate this two files
.\\
| lc3-vm.exe
| memory\_reports\_[DAY-MONTH-YEAR]\_[HOUR-MIN-SEC]\_final.log
| memory\_reports\_[DAY-MONTH-YEAR]\_[HOUR-MIN-SEC]\_init.log
File renamed without changes
Binary file modified lc3-vm.exe
Binary file not shown.
Binary file modified lc3-vm_gdb.exe
Binary file not shown.
2 changes: 1 addition & 1 deletion programs/hfu.htx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ F020 # trp x20 $ 0x3005
5920 # and r4 r4 x0 $ 0x3007
1820 # add r4 r0 x0 $ 0x3008
1034 # add r0 r0 -xB $ 0x3009
03F9 # brp x-6 $ 0x300A
03F9 # brp -x6 $ 0x300A
56E0 # and r3 r3 x0 $ 0x300B
E637 # lea r3 x37 $ 0x300C
5020 # and r0 r0 x0 $ 0x300D
Expand Down
38 changes: 17 additions & 21 deletions src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>

//----------------------------------------------------------
//Macros & Helpers

Expand All @@ -17,10 +18,10 @@
typedef unsigned char u8; // 8 bits unsigned integer | inteiro sem sinal de 8 bits
typedef unsigned short u16; // 16 bits unsigned integer | inteiro sem sinal de 16 bits
typedef unsigned int u32; // 32 bits unsigned integer | inteiro sem sinal de 32 bits

#define U16_MAX 0b1111111111111111 // Max value for unsigned 16bit integer | Valor máximo para inteiro sem sinal de 16 bits

//? Uncomment these to use rti or res | descomente-os para poder usar rti ou res
//#define RTI_IMPLEMENTED //!NEED IMPLEMENTATION TO USE | PRECISA DE IMPLEMENTAÇÃO PARA USAR
//? Uncomment this to use res | descomente para poder usar res
//#define RES_VALID


Expand All @@ -39,8 +40,8 @@ typedef unsigned int u32; // 32 bits unsigned integer | inteiro sem si
#define TRP(inst) ((inst)&0xFF) // macro to get the trap vector | Macro para pegar o vetor da operação trap
#define CHR1(ptr) ((char)((*ptr)&0xFF)) // macro to get the first char of a word | Macro para pegar o primeiro char de uma word
#define CHR2(ptr) ((char)((*ptr>>8)&0xFF))// macro to get the seconde char of a word | Macro para pegar o segundo char de uma word
#define TXTCLR(ptr) (30+(((*ptr)>>8)&0x0F)) // macro to get the text color
#define BCKCLR(ptr) (40+(((*ptr)>>12)&0xFF))// macro to get the background color
#define TXTCLR(ptr) (30+(((*ptr)>>8)&0x0F)) // macro to get the text color | Macro para pegar a cor do texto
#define BCKCLR(ptr) (40+(((*ptr)>>12)&0xFF))// macro to get the background color | Macro para pegar a cor de fundo

#define CLRRESET "\x1b[0m" // macro to reset color

Expand Down Expand Up @@ -135,12 +136,7 @@ typedef void (*trp_executor_f)();
}
/*0x8|0b1000*/ VM_LC3 void rti (u16 inst)
{
//!NOT IMPLEMENTED | NÃO IMPLEMENTADO
#if defined RTI_IMPLEMENTED
//rti implementation here
#else
exit(1);
#endif
}
/*0x9|0b1001*/ VM_LC3 void not (u16 inst)
{
Expand All @@ -164,11 +160,11 @@ typedef void (*trp_executor_f)();
{
//! NOT EXIST IN OFFICIAL LC-3 | NÃO EXISTE NO LC-3 OFICIAL
#if defined RES_VALID
reg[RPC] = PC_START;
for (register u8 i = 0; i < RCNT; i++)
{
reg[i] = 0;
}
reg[RPC] = PC_START;
#else
exit(1);
#endif
Expand Down Expand Up @@ -253,7 +249,7 @@ op_executor_f op_execute[OPS] = {br, add, ld, st, jsr, and, ldr, str, rti, not,
//----------------------------------------------------------
//Load programs and main loop

void run(u16 offset)
void run(short offset)
{
fprintf(stdout,"\x1b[36m""Starting VM...\n\n""\x1b[0m");
reg[RPC] = PC_START + offset;
Expand All @@ -263,17 +259,16 @@ void run(u16 offset)
op_execute[OPC(instruction)](instruction);
}
}
void load_image(const char* image_path, u16 offset)
void load_image(const char* image_path, short offset)
{
FILE* img = fopen(image_path, "rb");
if(img == NULL){
fprintf(stderr,"\x1b[31m""ERR: Failed to open program image file %s\n""\x1b[0m",image_path);
exit(1);
}


u16* p = memory + PC_START + offset;
fread(p,sizeof(u16),(U16_MAX-PC_START),img);
fread(p,sizeof(u16),(U16_MAX-(PC_START + (short)offset)),img);

fclose(img);
}
Expand All @@ -287,7 +282,7 @@ void memory_report(const char* name)
fprintf(stderr,"\x1b[31m""ERR: Failed to create memory report""\x1b[0m");
exit(1);
}
fprintf(memrep,"-----[ 0x0000 0x0001 0x0002 0x0003 0x0004 0x0005 0x0006 0x0007 0x0008 0x0009 0x000A 0x000B 0x000C 0x000D 0x000E 0x000F ]\n");
fprintf(memrep,"-----[ 0x###0 0x###1 0x###2 0x###3 0x###4 0x###5 0x###6 0x###7 0x###8 0x###9 0x###A 0x###B 0x###C 0x###D 0x###E 0x###F ]\n");
for (size_t i = 0; i < 4096; i++)
{
fprintf(memrep,"#%03X:[ 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X ]\n",i,memread(16*i+0),memread(16*i+1),memread(16*i+2),memread(16*i+3),memread(16*i+4),memread(16*i+5),memread(16*i+6),memread(16*i+7),memread(16*i+8),memread(16*i+9),memread(16*i+0xA),memread(16*i+0xB),memread(16*i+0xC),memread(16*i+0xD),memread(16*i+0xE),memread(16*i+0xF));
Expand All @@ -300,8 +295,7 @@ void help(void);

int main(int argc, char const *argv[])
{
size_t runoff = 0x0, loadoff = 0x0;
u32 arg = 2;
short runoff = 0x0, loadoff = 0x0;
u8 mrp = 0;
char mrn[128] = "memory_report_",init_log[128] = "", final_log[128] = "", time_str[64] = "";
time_t exec_time;
Expand All @@ -321,14 +315,14 @@ int main(int argc, char const *argv[])
}


fprintf(stdout,"\x1b[36m""Setting up VM\n",PC_START + runoff);
fprintf(stdout,"\x1b[36m""Setting up VM\n");
for(u32 i = 2; i < argc; i++)
{
if(!strcmp(argv[i], "--memrep")) mrp = 1;

if(!strcmp(argv[i],"--runoff")) sscanf(argv[i+1],"%x",&runoff);
if(!strcmp(argv[i],"--runoff")) sscanf(argv[i+1],"%hx",&runoff);

if(!strcmp(argv[i],"--loadoff")) sscanf(argv[i+1],"%x",&loadoff);
if(!strcmp(argv[i],"--loadoff")) sscanf(argv[i+1],"%hx",&loadoff);
}
if(mrp)
{
Expand All @@ -345,7 +339,9 @@ int main(int argc, char const *argv[])
fprintf(stdout,"\x1b[36m""Load program image origin setted to %X\n""\x1b[0m",PC_START + loadoff);

fprintf(stdout,"\x1b[36m""Loading program to memory...\n""\x1b[0m");
load_image(argv[1],loadoff);

load_image(argv[1],loadoff);

fprintf(stdout,"\x1b[36m""Program Loaded to memory\n""\x1b[0m");

if(mrp) memory_report(init_log);
Expand Down

0 comments on commit 1cc8977

Please sign in to comment.