~rabbits/orca-toy

0808b5b6caaea30bcdd0def91af53f5332ce448b — neauoire 2 years ago ffb6e29
Started basics
3 files changed, 109 insertions(+), 87 deletions(-)

M README.md
M demo.orca
M toy.c
M README.md => README.md +38 -79
@@ 1,79 1,38 @@
# GYO

[Gyo](https://wiki.xxiivv.com/site/gyo.html) is an imaginary computer with 16 registers, 256 addressable memory addresses. The cpu understands 16 opcodes, the assembler syntax understands `=constants` and `:labels`. Programs are loaded directly into memory to create procedural self-modifiable programs.

<img src='https://wiki.xxiivv.com/media/generic/gyo.jpg' width='200'/>

## Instructions

```
0x0  BRK  Break
0x1  JMP  Jump to position in memory
0x2  JCA  Jump to position in memory, when carryflag
0x3  JZE  Jump to position in memory, when zeroflag
0x4  PEK  Read status
0x5  POK  Write status
0x6  GET  Store in register
0x7  PUT  Store in memory
0x8  ADD  Add value to register, set carryflag when overflow
0x9  SUB  Substract value from register, set carryflag when overflow
0xA  EQU  Compare register with value, set zeroflag when equal
0xB  LES  Compare register with value, set zeroflag when less than
0xC  AND  Bitwise AND operator
0xD  XOR  Bitwise XOR operator
0xE  ROL  Bitwise rotate left
0xF  ROR  Bitwise rotate right
```

## Addressing

- `#ef` the raw value.
- `$ef` the value at address #ef in memory.
- `[e]` the value of the 15th register.
- `{e}` the value at the address of the 15th register.

## IO

To begin IO mode, activate the traps flag with `POK #08`.

```
POK #08  ; Set traps flag ON
GET      ; Read character from stdin
PUT [0]  ; Write character to stdout
POK #00  ; Set traps flag OFF 
```

## Status Register

The status register is distributed as follows, it shares the same byte as the register selector. The **halt** flag is used by the BRK instruction is stops the cpu, the **zero** flag is used for conditional instructions(EQU/LES/JEQ/JNE), the **carry** flag is set when a SUB/ADD instruction carries over the 8bit range and the **traps** flag is set when the pointer should be sent to the traps location(in IO operations). 

```
T C Z H
| | | +---- Halt
| | +------ Zero
| +-------- Carry
+---------- Traps
```

## Assembly Syntax

```
=rate #01           ; defines constant value

:label              ; a label defines an address in the program
	ADD rate        ; add rate to register
	EQU #0f         ; set zeroflag if register is equal to #0f
	JZE end         ; goto end if equal
	JMP label       
:end
	BRK
```

If you need to fill the memory with specific values, you can do it as follows:

```
:hello
	#48 #65
	#6C #6C
	#6F #0A
```
\ No newline at end of file
# Orca(toy)

Orca is an [esoteric programming language](https://en.wikipedia.org/wiki/Esoteric_programming_language) designed to quickly create procedural sequencers, in which every letter of the alphabet is an operation, where lowercase letters operate on bang, uppercase letters operate each frame.

This is a single-file toy implementation, written in ANSI C, of the basic operators created for educational purposes.

## Operators

To display the list of operators inside of Orca, use `CmdOrCtrl+G`.

- `A` **add**(*a* b): Outputs sum of inputs.
- `B` **subtract**(*a* b): Outputs difference of inputs.
- `C` **clock**(*rate* mod): Outputs modulo of frame.
- `D` **delay**(*rate* mod): Bangs on modulo of frame.
- `E` **east**: Moves eastward, or bangs.
- `F` **if**(*a* b): Bangs if inputs are equal.
- `G` **generator**(*x* *y* *len*): Writes operands with offset.
- `H` **halt**: Halts southward operand.
- `I` **increment**(*step* mod): Increments southward operand.
- `J` **jumper**(*val*): Outputs northward operand.
- `K` **konkat**(*len*): Reads multiple variables.
- `L` **less**(*a* *b*): Outputs smallest of inputs.
- `M` **multiply**(*a* b): Outputs product of inputs.
- `N` **north**: Moves Northward, or bangs.
- `O` **read**(*x* *y* read): Reads operand with offset.
- `P` **push**(*len* *key* val): Writes eastward operand.
- `Q` **query**(*x* *y* *len*): Reads operands with offset.
- `R` **random**(*min* max): Outputs random value.
- `S` **south**: Moves southward, or bangs.
- `T` **track**(*key* *len* val): Reads eastward operand.
- `U` **uclid**(*step* max): Bangs on Euclidean rhythm.
- `V` **variable**(*write* read): Reads and writes variable.
- `W` **west**: Moves westward, or bangs.
- `X` **write**(*x* *y* val): Writes operand with offset.
- `Y` **jymper**(*val*): Outputs westward operand.
- `Z` **lerp**(*rate* target): Transitions operand to input.
- `*` **bang**: Bangs neighboring operands.
- `#` **comment**: Halts a line.

M demo.orca => demo.orca +4 -4
@@ 1,6 1,6 @@
...........
.S.........
...........
...........
.E.........
...........
.......S...
.......0...
..E........
........E0.

M toy.c => toy.c +67 -4
@@ 5,6 5,7 @@ typedef struct Grid {
	int height;
	int length;
	char data[256 * 256];
	int lock[256 * 256];
} Grid;

int


@@ 15,19 16,81 @@ error(char *name)
}

void
run(FILE *f, Grid *g)
lock(Grid *g, int x, int y, int b)
{
	g->lock[x + (y * g->width)] = b;
}

int
busy(Grid *g, int x, int y)
{
	return g->lock[x + (y * g->width)];
}

char
get(Grid *g, int x, int y)
{
	return g->data[x + (y * g->width)];
}

void
set(Grid *g, int x, int y, char c)
{
	g->data[x + (y * g->width)] = c;
}

void
parse(Grid *g)
{
	int i, x, y;
	printf("F0\n");
	for(i = 0; i < g->length; ++i) {
		printf("%c", g->data[i]);
	}
	printf("DEBUG\n");
	for(i = 0; i < g->length; ++i) {
		char c = g->data[i];
		x = i % g->width;
		y = i / g->width;
		if(busy(g, x, y))
			continue;
		if(c == 'E') {
			if(get(g, x + 1, y) == '.') {
				set(g, x, y, '.');
				set(g, x + 1, y, 'E');
				lock(g, x + 1, y, 1);
			} else
				set(g, x, y, '*');
		} else if(c == 'S') {
			if(get(g, x, y + 1) == '.') {
				set(g, x, y, '.');
				set(g, x, y + 1, 'S');
				lock(g, x, y + 1, 1);
			} else
				set(g, x, y, '*');
		}
	}
	printf("F1\n");
	for(i = 0; i < g->length; ++i) {
		printf("%c", g->data[i]);
	}
}

void
load(FILE *f, Grid *g)
{
	char c;
	g->length = 0;
	while((c = fgetc(f)) != EOF) {
		if(c == '\n') {
			if(g->width == 0)
				g->width = g->length;
				g->width = g->length + 1;
			g->height = g->length / g->width;
		}
		g->length++;
		g->data[g->length++] = c;
	}
	printf("grid:%d(%dx%d)\n", g->length, g->width, g->height);
	parse(g);
}

int


@@ 40,6 103,6 @@ main(int argc, char *argv[])
	f = fopen(argv[1], "r");
	if(f == NULL)
		return error("Missing input.");
	run(f, &g);
	load(f, &g);
	return 0;
}