diff options
| author | Nakidai <nakidai@disroot.org> | 2025-07-24 08:30:00 +0300 |
|---|---|---|
| committer | Nakidai <nakidai@disroot.org> | 2025-07-24 08:30:00 +0300 |
| commit | f09b4adbc7776cfce4c3762968edc82460956f92 (patch) | |
| tree | 9a46545219a636ad89d5025c2776a8e08a112c83 | |
| download | pps-f09b4adbc7776cfce4c3762968edc82460956f92.tar.gz pps-f09b4adbc7776cfce4c3762968edc82460956f92.zip | |
Add code v1.0.0
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | README | 22 | ||||
| -rw-r--r-- | example.S | 67 | ||||
| -rw-r--r-- | pps.c | 108 |
5 files changed, 201 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf3e96e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +pps diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f47c4cb --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +all: pps +clean: + rm -f pps diff --git a/README b/README new file mode 100644 index 0000000..5651f66 --- /dev/null +++ b/README @@ -0,0 +1,22 @@ +Prototype Processor aSsembler + +computer architecture[1] is by qubane[2]; +assembler is by nakidai[3] and released in public domain + +pros: +- factored out emit() function so it can be replaced with something more + suitable for your specific use case +- case insensitive where not needed +- `inc' mnemonic that includes some other file +cons: +- doesn't handle comments very good, but still (start line with `; ' to make + one) +- code is garbage a little +other: +- lda instruction uses atoi for number converting, hence number base there is 10 +- register check is case insensitive by 1 letter, so e.g. ACC can be named as a, + AcC, acC, AR etc + +[1] https://docs.google.com/spreadsheets/d/1ESjhZcvpGmuHCNxgOESfSy-MXQoqrMqCyCDJyvDhRMM/edit?usp=sharing +[2] https://github.com/qubane +[3] https://nakidai.ru diff --git a/example.S b/example.S new file mode 100644 index 0000000..530501a --- /dev/null +++ b/example.S @@ -0,0 +1,67 @@ +; Fibonacci sequence program by qubane + +; address for var A +CA +MOVC MR + +; write 0 +WT + +; address for var B +LDA 1 +MOVC MR + +; write 1 +WT + +; loop start +; load address for var A +CA +MOVC MR + +; move var A to BR +RD +MOV BR + +; load address for var B +CA +LDA 1 +MOVC MR + +; read var B +RD + +; A + B -> B +ADD +WT + +; move A + B to BR +MOV BR + +; load address for var A +CA +; clear carry flag +AND +MOVC MR + +; read var A +RD + +; compute -(A - B) +SUB + +MOV BR + +CA +SUB + +; write B - A to var A +WT + +; load jump address +CA +; reset carry flag +and +LDA 1 +LDA 2 +MOVC PC diff --git a/pps.c b/pps.c new file mode 100644 index 0000000..1bcba88 --- /dev/null +++ b/pps.c @@ -0,0 +1,108 @@ +/* + * Prototype Processor aSsembler + * + * Computer architecture is by qubane + * Assembler is by nakidai and released in public domain + */ + +#include <ctype.h> +#include <err.h> +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + + +#define LINESZ 128 + +#define is(x, y) if (!strcmp((x), (y))) + +char line[LINESZ]; + +void parsefile(const char *); + +void emit(char inst) +{ + printf("%04b\n", (int)inst); +} + +void tolowers(char *s) +{ + for (; *s; ++s) + *s = tolower(*s); +} + +int parsereg(const char *name) +{ + switch (*name) + { + case 'b': return 0; + case 'm': return 1; + case 'p': return 2; + default: return -1; + } +} + +void parseline(char *line, const char *path, size_t n) +{ + char *arg = strchr(line, ' '), + *end = strchr(line, '\n'); + + arg && (*arg = 0); + end && (*end = 0); + + if (!*line) + return; + + tolowers(line); + + if (!arg++) + is (line, "ca") emit(8); + else is (line, "add") emit(9); + else is (line, "sub") emit(10); + else is (line, "and") emit(11); + else is (line, "or") emit(12); + else is (line, "xor") emit(13); + else is (line, "rd") emit(14); + else is (line, "wt") emit(15); + else is (line, ";") ; + else errx(1, "%s:%d: invalid instruction: %s", path, n, line); + else + is (line, "lda") + emit(atoi(arg)); + else is (line, "movc") + if (tolowers(arg), parsereg(arg) < 0) + errx(1, "%s:%lu: invalid instruction: %s %s", path, n, line, arg); + else + emit(4 + parsereg(arg)); + else is (line, "mov") + if (tolowers(arg), parsereg(arg) != 0) + errx(1, "%s:%lu: invalid instruction: %s %s", path, n, line, arg); + else + emit(7); + else is (line, "inc") parsefile(arg); + else is (line, ";"); + else errx(1, "%s:%lu invalid instruction: %s %s", path, n, line, arg); +} + +void parsefile(const char *file) +{ + FILE *fp = fopen(file, "r"); + size_t n = 0; + + if (!fp) + err(1, "fopen(%s)", file); + + while (fgets(line, sizeof(line), fp)) + parseline(line, file, n++); + + if (ferror(fp)) + err(1, "fgets(%s)", file); +} + +int main(int argc, char **argv) +{ + if (!argv[1] || !*argv[1]) + return fprintf(stderr, "usage: %s <filename>\n", *argv), 1; + parsefile(argv[1]); +} |