Skip to content

Commit

Permalink
Merge pull request #5 from robalb/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
robalb authored Nov 1, 2024
2 parents 992f813 + 72cead0 commit 5b594e8
Show file tree
Hide file tree
Showing 36 changed files with 1,925 additions and 611 deletions.
135 changes: 77 additions & 58 deletions emscripten_blink/blink/blink/blinkenlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,37 @@
#include <stdio.h>
#include <signal.h>

void update_clstruct(struct Machine *m);

/*
* These variables are defined by javascript;
* the pointers are passed to main when this module starts
*/
void(*signal_callback)(int, int) = 0;
void(*exit_callback)(int) = 0;

void update_clstruct(struct Machine *m);


/**
/*
* this buffer holds the disassembly strings
* that will be passed to js
*/
#define DIS_MAX_LINES 200
#define DIS_MAX_LINE_LEN 200
char dis_buffer[DIS_MAX_LINES][DIS_MAX_LINE_LEN] = {0};

/*
* These buffers hold the program execution arguments.
* The pointers to these strings will be passed to js,
* and the content will be dynamically set by js
*/
#define ARGC_MAX_LINE_LEN 200
#define ARGV_MAX_LINE_LEN 200
#define PROGNAME_MAX_LINE_LEN 200
char argc_string[ARGC_MAX_LINE_LEN] = {0};
char argv_string[ARGV_MAX_LINE_LEN] = {0};
char progname_string[PROGNAME_MAX_LINE_LEN] = {0};

struct clstruct cls;
struct System *s;
struct Machine *m;
Expand Down Expand Up @@ -276,94 +293,81 @@ void TearDown(void) {
memset(dis_buffer, 0, sizeof(dis_buffer));
}

void stringToArgsArray(char *argsString, char **argsArray, int maxArgs) {
int count = 0;
char *token = strtok(argsString, " ");
while (token != NULL && count < maxArgs - 1) {
argsArray[count++] = token;
token = strtok(NULL, " ");
}
argsArray[count] = NULL;
}

void setupProgramWithArgs(char* programpath, char **args, bool withdebugger){
/**
* Set up a program using the arguments previously set
* by javascript in the global strings:
* - progname_string
* - argc_string
* - argv_string
*
*/
void setupProgram(bool withdebugger){
debugger_enabled = withdebugger;

//terminal prompt
printf("\n$ %s\n", argc_string);

//get **argc
char *args[ARGC_MAX_LINE_LEN];
char argc_string_copy[ARGC_MAX_LINE_LEN];
memcpy(argc_string_copy, argc_string, ARGC_MAX_LINE_LEN);
stringToArgsArray(argc_string_copy, args, ARGC_MAX_LINE_LEN);

//get **argv
//TODO
char *vars = 0;

//close previous instances
TearDown();
char *bios = 0;
char *vars = 0;
SetUp();
LoadProgram(m, programpath, programpath, args, &vars, bios);
#ifdef DEBUG
printf("loaded: %d, exited: %d\n", s->loaded, s->exited);
#endif
char *bios = 0;
LoadProgram(m, progname_string, progname_string, args, &vars, bios);
PostLoadSetup();
update_clstruct(m);
}

void setupProgram(){
//TODO: all this must be received as arg.
//remember to free these strings after they are used, since
//they will be allocated dynamically from js
char codepath[] = "/program";
char *args[] = {"/program", 0};
puts("/program");
setupProgramWithArgs(codepath, args, true);
}


////////////////////////
///exported api
////////////////////////


EMSCRIPTEN_KEEPALIVE
void blinkenlib_loadProgram(){
//this is currently fully implemented in js.
//the elf is fetched js-side, and put in the
//vfs at the path ./program
}

EMSCRIPTEN_KEEPALIVE
void blinkenlib_loadPlayground(int step){
#define STEP_ASSEMBLE_AND_LINK 0
#define STEP_ASSEMBLE 1
#define STEP_LINK 2
if(step == STEP_ASSEMBLE_AND_LINK){
puts("\n/fasm /assembly.s /program");
char codepath[] = "/fasm";
char *args[] = {"/fasm", "/assembly.s", "/program", 0};
setupProgramWithArgs(codepath, args, false);
single_stepping = false;
runLoop();
}
else if(step == STEP_ASSEMBLE){
puts("\n/as -o /program.o /assembly.s");
char codepath[] = "/as";
char *args[] = {"/as", "-o", "/program.o", "/assembly.s", 0};
setupProgramWithArgs(codepath, args, false);
single_stepping = false;
runLoop();
}
else if(step == STEP_LINK){
puts("\n/ld -o /program /program.o");
char codepath2[] = "/ld";
char *args2[] = {"/ld", "--no-dynamic-linker", "-o", "/program", "/program.o", 0};
setupProgramWithArgs(codepath2, args2, false);
single_stepping = false;
runLoop();
puts("Program ready.");
}
void blinkenlib_run_fast(){
setupProgram(false);
single_stepping = false;
runLoop();
}


EMSCRIPTEN_KEEPALIVE
void blinkenlib_run(){
setupProgram();
setupProgram(true);
//run the program to the end
single_stepping = false;
runLoop();
}

EMSCRIPTEN_KEEPALIVE
void blinkenlib_starti(){
setupProgram();
setupProgram(true);
//don't run any instruction
}

EMSCRIPTEN_KEEPALIVE
void blinkenlib_start(){
setupProgram();
setupProgram(true);
//TODO: set breakpoint at main
single_stepping = false;
runLoop();
Expand Down Expand Up @@ -393,6 +397,21 @@ void *blinkenlib_get_clstruct(){
return &cls;
}

EMSCRIPTEN_KEEPALIVE
void *blinkenlib_get_argc_string(){
return &argc_string;
}

EMSCRIPTEN_KEEPALIVE
void *blinkenlib_get_argv_string(){
return &argv_string;
}

EMSCRIPTEN_KEEPALIVE
void *blinkenlib_get_progname_string(){
return &progname_string;
}

EMSCRIPTEN_KEEPALIVE
u8 *blinkenlib_spy_address(u64 virtual_address){
BEGIN_NO_PAGE_FAULTS;
Expand All @@ -408,7 +427,7 @@ int main(int argc, char *argv[]) {
#endif
puts("Initializing blink emulator...");
if(argc != 3){
puts("Error. main expected 2 args");
puts("Error. main expected 3 args");
return 1;
}
int signal_callback_num = atoi(argv[1]);
Expand Down
8 changes: 5 additions & 3 deletions emscripten_blink/blink/blink/blinkenlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,20 @@ struct clstruct{
//disassembly buffer
u32 dis__max_lines; //number
u32 dis__max_line_len; //number
u32 dis__current_line; //number
u32 dis__current_line; //number
u32 dis__buffer;
};

void blinkenlib_loadProgram();
void blinkenlib_loadPlayground(int stage);
void blinkenlib_run_fast();
void blinkenlib_run();
void blinkenlib_start();
void blinkenlib_starti();
void blinkenlib_stepi();
void blinkenlib_continue();
void *blinkenlib_get_clstruct();
void *blinkenlib_get_argc_string();
void *blinkenlib_get_argv_string();
void *blinkenlib_get_progname_string();
u8 *blinkenlib_spy_address(u64 virtual_address);

#endif /* BLINK_BLINKENLIB_H_ */
Expand Down
48 changes: 47 additions & 1 deletion emscripten_blink/field_notes/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,58 @@
-[x] first release with github pages
-[x] CI/CD pipeline. pushes to master should trigger a merge and then a checkout into github_pages. then trigger a build. the contents of /build should be copied into /docs, and pushed.
- test CI/CD pipeline that directly publishes to github pages without storing the artifacts in a branch. -> https://github.com/actions/upload-pages-artifact
- mobile layout
-[x] mobile layout

-[x] Figure out design system:
- what about MELT ui, styling every melt ui element via the data-attributes the library sets?
overrides should be easy via custom styles.
- what about elements that are not controlled by melt ui? such as basic buttons? https://www.w3.org/WAI/ARIA/apg/patterns/menubar/



## todo week 4

Story:

TODO: a complete refactor of the mode key.
mode should be set via a specific setter, and should be an Assemblers_key.
it should be used to render the assembler dropdown menu, together with the assemblers object.
changes to mode should not trigger changes to the Editor content.

We then need a way to reactively set the Editor content.

We then need a function to set the webapp state (for now, assembler mode and editor content, but in the future
there could be more options).
When a demo is selected this function is called.
we also need several serializers and deserializers compatible with this webappState.
when you click "share", the current webappState is serialized into an url.
when the page loads, or the url changes, some url param is deserialized and passed to
setWebAppstate.

we should refactor snippets.js into example_scripts.ts.
every example should be the combo codestring,Assemblers_key.
we can then create a custom webappstate serializer that takes this combo and
generates a webappstate, that is passed to setWebAppState


actual Todo list:

- [x] uri manager and uri appstate serializers
- define diagnosticparser interface, associated to an assemblerMode.
a diagnosticParse should parse the stout of a compiler when assembly fails,
generating a standardized diagnostic output that is used by the editor to render error lines
- add line error support to the editor.
this snippet shows how to tap in the editor renderer to add line highlights
https://stackblitz.com/edit/vitejs-vite-y5pwon?file=src%2Fmain.ts,readme.md
In the editor component, we'll need to listen to store.diagnostics, and when
they are not null, render them.
in store.notifyEditorContent we should add a line that resets the diagnostics


### backlog
- editor tooltip for asm guide, like in compiler explorer
https://stackblitz.com/edit/vitejs-vite-z2fgpu?file=src%2Fmain.ts
- invert taborder in the control rows. on desktop the current order is bad
- service worker. Understand: is github pages good enough for caching?
can i solve eventual caching issues with service workers?
https://web.dev/articles/service-worker-lifecycle
Expand Down
Loading

0 comments on commit 5b594e8

Please sign in to comment.