diff options
| author | 2025-08-07 12:19:32 +0330 | |
|---|---|---|
| committer | 2025-08-07 12:19:32 +0330 | |
| commit | 47b04ca2778cbce41deae6331472c25822e7a29a (patch) | |
| tree | c6b4f555e2f890dfd2e8dfc75f61ff11e0ade3a4 | |
| parent | char fix (diff) | |
bwahh changes!!
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | README.md | 9 | ||||
| -rw-r--r-- | code.pasm | 6 | ||||
| -rw-r--r-- | pu.c | 137 | ||||
| -rw-r--r-- | pu.out.c | 9 | ||||
| -rw-r--r-- | t | bin | 0 -> 115 bytes |
6 files changed, 143 insertions, 20 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d56a83a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +pu +putest
\ No newline at end of file @@ -13,4 +13,11 @@ ikr,,, ## instruction set? check the comments in pu.c -i still haven't added docs for the assembler, but ehh it's pretty self explanatory. ask ai to explain it to you if you can't be assed to read.
\ No newline at end of file +i still haven't added docs for the assembler, but ehh it's pretty self explanatory. ask ai to explain it to you if you can't be assed to read. + +## t? +that file is the instruction encoding table for the assembler. you can add shit to it if you wanna. this is the original: +```c +char *R="hlt\0 ar1\2 ar2\3 ar3\4 ar4\5 ar5\6 ar6\7 ar7\x8 ar8\x9 r1a\xA r2a\xB r3a\xC r4a\xD r5a\xE r6a\xF r7a\20 r8a\21 mem\22 aca\23 add\24 sub\25 not\26 clr\27"; +``` +removing it means you can't assemble stuff anymore. though the pu.c wrapper does write it for you if it doesn't exist.
\ No newline at end of file diff --git a/code.pasm b/code.pasm new file mode 100644 index 0000000..969f96b --- /dev/null +++ b/code.pasm @@ -0,0 +1,6 @@ +# charcode for c +con 99 + +ar4 con 60 ar2 r4a mem con 1 ar4 con 60 ar3 con 0 ar2 con 2 hlt + +hlt @@ -1,12 +1,16 @@ +#include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include <string.h> -#include <stdio.h> #pragma clang diagnostic ignored "-Wreturn-type" #pragma clang diagnostic ignored "-Wc23-extensions" +// clang-format off #define S 65536 #define H !--c? -m[S],c,a;pu(){while((c=m[m[7]++]))H*m=m[m[7]++]:c--<9?a?m[c]=*m:0:8>(c-=8)?*m=m[c]:!(c-=8)?m[m[1]]=*m:H*m=a:H a+=*m:H a-=*m:H a=!a:H a=0:0;} +#define J while +m[S],c,a;pu(){J((c=m[m[7]++]))H*m=m[m[7]++]:c--<9?!a?m[c]=*m:0:8>(c-=8)?*m=m[c]:!(c-=8)?m[m[1]]=*m:H*m=a:H a+=*m:H a-=*m:H a=!a:H a=0:0;} +// clang-format on // a is acc // first 8 memory bytes are registers actually @@ -15,7 +19,7 @@ m[S],c,a;pu(){while((c=m[m[7]++]))H*m=m[m[7]++]:c--<9?a?m[c]=*m:0:8>(c-=8)?*m=m[ // --- opcodes --- // 0 = halt DONE // 1 = const in r0 DONE -// 2...9 = r0 in rX (only if acc is non-zero) DONE +// 2...9 = r0 in rX (only if acc is zero) DONE // 10...17 = rX in r0 DONE // 18 = r0 in m[r1] DONE // 19 = acc in r0 DONE @@ -29,28 +33,127 @@ m[S],c,a;pu(){while((c=m[m[7]++]))H*m=m[m[7]++]:c--<9?a?m[c]=*m:0:8>(c-=8)?*m=m[ // compiler! // the switch skips whitespace. then, the beautiful loop thingymajigy emits bytecode. +// clang-format off #define W case #define Q goto M; -char *R="hlt\0 ar1\2 ar2\3 ar3\4 ar4\5 ar5\6 ar6\7 ar7\x8 ar8\x9 r1a\xA r2a\xB r3a\xC r4a\xD r5a\xE r6a\xF r7a\20 r8a\21 mem\22 aca\23 add\24 sub\25 not\26 clr\27";K;as(char*I,int*O){char*V=R;while((K=*I)){V=R;switch(K){case 32:case 10:case 9:I++;Q}while(*V)V+=3,(strncmp(V-3,I,3)?:({*O++=*V;I+=3;Q})),V+=2;strncmp("con ",I,4)?:({*O++=1,*O++=atoi(I+=4);while(*I>47&*I<58)I++;Q});return 1;M:}return 0;} +char R[]={ +#embed"t" +};K;char*as(char*I,int*O){char*V=R;J((K=*I)){V=R;switch(K){W 32:W 10:W 9:I++;Q;W 35:J(*++I!=10);Q}strncmp("con ",I,4)?:({*O++=1,*O++=atoi(I+=4);J(*I>47&*I<58)I++;Q});J(*V)V+=3,(strncmp(V-3,I,3)?:({*O++=*V;I+=3;Q})),V+=2;return I;M:}return 0;} +// clang-format on #undef Q #undef H #undef W #undef S - -// ---------- +#undef J #ifndef __WRAPPER -int main() { - // __asm__("int $3"); - m[ 7 ] = 1024; - m[ 1024 ] = 1; - m[ 1025 ] = 9; - m[ 1026 ] = 1; - m[ 1027 ] = 5; - - printf("before: %i\n", m[ 0 ]); - pu(); - printf("after: %i\n", m[ 0 ]); + +// runs pu until exit code != 2, +// that exit code is an interrupt for talking to the emulated hardware +int emu() { + while (1) { + pu(); + int e_code = m[ 0 ]; + + if (e_code != 2) return e_code; + + // handle hardware interrupts + int int_code = m[ 1 ]; + + // 0: output string + if (int_code == 0) { + int ptr = m[ 2 ]; + int size = m[ 3 ], i = 0; + + for (; i < size; i++) putchar(m[ ptr++ ]); + write(STDOUT_FILENO, &m[ ptr ], size); + } + + // 1: input character + else if (int_code == 1) { + m[ 2 ] = getchar(); + } + + else { + // unknown interrupt. what to do? + } + + m[ 0 ] = 0; + m[ 7 ]++; + } +} + +char R_backup[] = "hlt\0 ar1\2 ar2\3 ar3\4 ar4\5 ar5\6 ar6\7 ar7\x8 ar8\x9 r1a\xA r2a\xB r3a\xC " + "r4a\xD r5a\xE r6a\xF r7a\20 r8a\21 mem\22 aca\23 add\24 sub\25 not\26 clr\27"; + +int main(int argc, char **argv) { + if (access("t", F_OK)) { + // patch the instruction table incase you removed it. + printf("you've deleted t! i'll write it again for you.\n\n"); + FILE *fp = fopen("t", "w+"); + fwrite(R_backup, 1, sizeof(R_backup), fp); + fclose(fp); + memcpy(R, R_backup, sizeof(R_backup)); + } + + if (argc == 1) { + printf("Usage:\n %s <filename>", argv[ 0 ]); + exit(1); + } + + // read code + FILE *fp = fopen(argv[ 1 ], "r"); + fseek(fp, 0, SEEK_END); + int sz = ftell(fp); + rewind(fp); + char code[ sz + 1 ]; + fread(code, 1, sz, fp); + code[ sz ] = 0; + fclose(fp); + + // set pc + m[ 7 ] = 1024; + // assemble + char *fail_point = as(code, &m[ 1024 ]); + + if (fail_point != 0) { + int error_pos = (int) (fail_point - code); + int i; + + int line = 1, col = 1; + for (i = 0; i < error_pos && i < sz; i++) { + if (code[ i ] == '\n') { + line++; + col = 1; + } else { + col++; + } + } + + fprintf( + stderr, "Assembly failed at line %d, column %d (position %d):\n", line, col, error_pos); + + int line_start = error_pos; + while (line_start > 0 && code[ line_start - 1 ] != '\n') { line_start--; } + + int line_end = error_pos; + while (line_end < sz && code[ line_end ] != '\n' && code[ line_end ] != '\0') { + line_end++; + } + + fprintf(stderr, " "); + for (i = line_start; i < line_end; i++) { fputc(code[ i ], stderr); } + fprintf(stderr, "\n"); + + fprintf(stderr, " "); + for (i = line_start; i < error_pos; i++) { fputc(' ', stderr); } + fprintf(stderr, "^ parsing stopped here\n"); + + exit(1); + } + + // run emulation + emu(); } #endif
\ No newline at end of file @@ -3,14 +3,19 @@ #pragma clang diagnostic ignored "-Wreturn-type" #pragma clang diagnostic ignored "-Wc23-extensions" +// clang-format off #define S 65536 #define H !--c? #define W case #define Q goto M; -m[S],c,a;pu(){while((c=m[m[7]++]))H*m=m[m[7]++]:c--<9?a?m[c]=*m:0:8>(c-=8)?*m=m[c]:!(c-=8)?m[m[1]]=*m:H*m=a:H a+=*m:H a-=*m:H a=!a:H a=0:0;} -char *R="hlt\0 ar1\2 ar2\3 ar3\4 ar4\5 ar5\6 ar6\7 ar7\x8 ar8\x9 r1a\xA r2a\xB r3a\xC r4a\xD r5a\xE r6a\xF r7a\20 r8a\21 mem\22 aca\23 add\24 sub\25 not\26 clr\27";K;as(char*I,int*O){char*V=R;while((K=*I)){V=R;switch(K){case 32:case 10:case 9:I++;Q}while(*V)V+=3,(strncmp(V-3,I,3)?:({*O++=*V;I+=3;Q})),V+=2;strncmp("con ",I,4)?:({*O++=1,*O++=atoi(I+=4);while(*I>47&*I<58)I++;Q});return 1;M:}return 0;} +#define J while +m[S],c,a;pu(){J((c=m[m[7]++]))H*m=m[m[7]++]:c--<9?!a?m[c]=*m:0:8>(c-=8)?*m=m[c]:!(c-=8)?m[m[1]]=*m:H*m=a:H a+=*m:H a-=*m:H a=!a:H a=0:0;}char R[]={ +#embed"t" +};K;as(char*I,int*O){char*V=R;J((K=*I)){V=R;switch(K){W 32:W 10:W 9:I++;Q;W 35:J(*++I!=10);Q}strncmp("con ",I,4)?:({*O++=1,*O++=atoi(I+=4);J(*I>47&*I<58)I++;Q});J(*V)V+=3,(strncmp(V-3,I,3)?:({*O++=*V;I+=3;Q})),V+=2;return 1;M:}return 0;} +// clang-format on #undef S #undef H +#undef J #undef Q #undef W
\ No newline at end of file Binary files differ |
