-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from suzukiplan/create-vgsasm
make vgsasm
- Loading branch information
Showing
22 changed files
with
1,391 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,3 +64,7 @@ tp_cmp2_b | |
tp_cmp2_c | ||
tp_cmp2_d | ||
tp_vgs | ||
vgsasm | ||
asmtest | ||
tp.bin | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
# Changes | ||
|
||
## Version 0.0.2 | ||
- `vgsasm` コマンドを実装 (注意: テスト未実施) | ||
|
||
## Version 0.0.1 | ||
- CPU実装完了 (APIはまだ全部揃っていない) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
#ifndef _WIN32 | ||
#include <sys/time.h> | ||
#endif | ||
#include "vgsasm.h" | ||
|
||
struct program_table { | ||
char input[1024]; | ||
char output[1024]; | ||
char* buffer; | ||
struct line_data* line; | ||
int line_number; | ||
} PT; | ||
|
||
static int check_arguments(int argc, char* argv[]) | ||
{ | ||
int i; | ||
memset(&PT, 0, sizeof(PT)); | ||
for (i = 1; i < argc; i++) { | ||
if (0 == strcmp("-o", argv[i])) { | ||
if (PT.output[0]) return -1; | ||
if (argc <= ++i) return -1; | ||
if (sizeof(PT.output) <= strlen(argv[i])) return -1; | ||
strcpy(PT.output, argv[i]); | ||
} else { | ||
if (PT.input[0]) return -1; | ||
if (sizeof(PT.input) <= strlen(argv[i])) return -1; | ||
strcpy(PT.input, argv[i]); | ||
} | ||
} | ||
if (!PT.input[0]) return -1; | ||
if (!PT.output[0]) { | ||
strcpy(PT.output, PT.input); | ||
char* ext = strrchr(PT.output, '.'); | ||
if (ext) *ext = '\0'; | ||
if (sizeof(PT.output) <= strlen(PT.output) + 4) return -1; | ||
strcat(PT.output, ".bin"); | ||
} | ||
return 0; | ||
} | ||
|
||
static void show_errors(struct line_data* line, int len) | ||
{ | ||
int i; | ||
int n = 0; | ||
for (i = 0; i < len; i++) { | ||
if (line[i].error[0]) { | ||
fprintf(stderr, "%s (line=%d)\n", line[i].error, line[i].number); | ||
n++; | ||
} | ||
} | ||
fprintf(stderr, "detected %d error%s.\n", n, 1 < n ? "s" : ""); | ||
} | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
FILE* fp; | ||
int i; | ||
|
||
#ifndef _WIN32 | ||
long usec; | ||
double sec; | ||
struct timeval tvStart; | ||
struct timeval tvEnd; | ||
gettimeofday(&tvStart, NULL); | ||
#endif | ||
|
||
if (check_arguments(argc, argv)) { | ||
puts("usage: vgsasm [-o output.bin] input.asm"); | ||
return 1; | ||
} | ||
LOGV("assembling: %s -> %s\n", PT.input, PT.output); | ||
|
||
PT.buffer = load_file(PT.input); | ||
if (NULL == PT.buffer) { | ||
fprintf(stderr, "file load error.\n"); | ||
return 2; | ||
} | ||
|
||
PT.line = parse_lines(PT.buffer, &PT.line_number); | ||
if (NULL == PT.line) { | ||
return 3; | ||
} | ||
|
||
remove_empty_line(PT.line, &PT.line_number); | ||
if (0 == PT.line_number) { | ||
fprintf(stderr, "empty source file.\n"); | ||
return 4; | ||
} | ||
|
||
parse_token(PT.line, PT.line_number); | ||
if (parse_operation(PT.line, PT.line_number)) { | ||
show_errors(PT.line, PT.line_number); | ||
return 5; | ||
} | ||
|
||
if (check_label(PT.line, PT.line_number)) { | ||
show_errors(PT.line, PT.line_number); | ||
return 6; | ||
} | ||
|
||
if (NULL == (fp = fopen(PT.output, "wb"))) { | ||
fprintf(stderr, "file open error.\n"); | ||
return 7; | ||
} | ||
|
||
for (i = 0; i < PT.line_number; i++) { | ||
if (PT.line[i].oplen) { | ||
if (PT.line[i].oplen != fwrite(PT.line[i].op, 1, PT.line[i].oplen, fp)) { | ||
fprintf(stderr, "file write error.\n"); | ||
return 8; | ||
} | ||
} | ||
} | ||
fclose(fp); | ||
free(PT.line); | ||
free(PT.buffer); | ||
|
||
#ifdef _WIN32 | ||
printf("success\n"); | ||
#else | ||
gettimeofday(&tvEnd, NULL); | ||
usec = tvEnd.tv_sec - tvStart.tv_sec; | ||
usec *= 1000000; | ||
usec += tvEnd.tv_usec; | ||
usec -= tvStart.tv_usec; | ||
sec = usec / 1000000.0; | ||
printf("success (%fsec)\n", sec); | ||
#endif | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include "vgscpu_internal.h" | ||
|
||
#define LOGV printf | ||
#define A1 0 | ||
#define A2 1 | ||
#define A4 2 | ||
#define B1 3 | ||
#define B2 4 | ||
#define B4 5 | ||
#define C1 6 | ||
#define C2 7 | ||
#define C4 8 | ||
#define D1 9 | ||
#define D2 10 | ||
#define D4 11 | ||
|
||
#define M1 1 | ||
#define M2 2 | ||
#define M4 4 | ||
|
||
#define ACU_ADD 0 | ||
#define ACU_SUB 1 | ||
#define ACU_MUL 2 | ||
#define ACU_DIV 3 | ||
#define ACU_MOD 4 | ||
#define ACU_AND 5 | ||
#define ACU_OR 6 | ||
#define ACU_XOR 7 | ||
#define ACU_CMP 8 | ||
#define ACU_CMP2 9 | ||
|
||
#define SHIFT_LEFT 0 | ||
#define SHIFT_RIGHT 1 | ||
|
||
struct line_data { | ||
char error[1024]; | ||
char* buffer; | ||
int number; | ||
char* token[8]; | ||
int toknum; | ||
unsigned char op[16]; | ||
int oplen; | ||
char branch_label[256]; | ||
int label_resolved; | ||
}; | ||
|
||
char* load_file(const char* path); | ||
void trimstring(char* src); | ||
int check_GR(char* token); | ||
int getHex(char c); | ||
int getDec(char c); | ||
int getOct(char c); | ||
int getBin(char c); | ||
int check_literal(char* token, unsigned int* result); | ||
int check_address(char* token, unsigned int* result, int* m); | ||
|
||
struct line_data* parse_lines(char* buf, int* line); | ||
void remove_empty_line(struct line_data* line, int* len); | ||
void parse_token(struct line_data* line, int len); | ||
int parse_operation(struct line_data* line, int len); | ||
int parse_push(struct line_data* line, int i); | ||
int parse_pop(struct line_data* line, int i); | ||
int parse_ld(struct line_data* line, int i); | ||
int parse_st(struct line_data* line, int i); | ||
int parse_inc(struct line_data* line, int i); | ||
int parse_dec(struct line_data* line, int i); | ||
int parse_not(struct line_data* line, int i); | ||
int parse_shift(struct line_data* line, int i, int lr); | ||
int parse_acu(struct line_data* line, int i, int acu); | ||
int _parse_arl(struct line_data* line, int i, int r, int op); | ||
int parse_branch(struct line_data* line, int i, unsigned char op); | ||
int parse_vgs(struct line_data* line, int i); | ||
int check_label(struct line_data* line, int len); |
Oops, something went wrong.