add consts
This commit is contained in:
parent
d8c9336261
commit
c351139f4d
@ -85,6 +85,9 @@ EvaledOperand eval_operand_to_imm(
|
|||||||
case IdentResolTy_Label:
|
case IdentResolTy_Label:
|
||||||
case IdentResolTy_SubLabel:
|
case IdentResolTy_SubLabel:
|
||||||
return (EvaledOperand) { .ty = EoTy_Imm, .imm = re->ip };
|
return (EvaledOperand) { .ty = EoTy_Imm, .imm = re->ip };
|
||||||
|
case IdentResolTy_Const:
|
||||||
|
return (EvaledOperand) { .ty = EoTy_Imm, .imm = re->value };
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "unreachable\n");
|
fprintf(stderr, "unreachable\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
57
asm/main.c
57
asm/main.c
@ -1,3 +1,4 @@
|
|||||||
|
#include "asm/report.h"
|
||||||
#include "assemble.h"
|
#include "assemble.h"
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
@ -91,6 +92,15 @@ int main(int argc, char** argv)
|
|||||||
.text_len = parser.lexer.text_len,
|
.text_len = parser.lexer.text_len,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
IdentResolver resolver;
|
||||||
|
ident_resolver_construct(&resolver);
|
||||||
|
|
||||||
|
OperandEvaluator evaluator = {
|
||||||
|
.re = &resolver,
|
||||||
|
.rep = &rep,
|
||||||
|
.second_pass = false,
|
||||||
|
};
|
||||||
|
|
||||||
size_t lines_capacity = 1024;
|
size_t lines_capacity = 1024;
|
||||||
PLine** lines = malloc(sizeof(PLine*) * lines_capacity);
|
PLine** lines = malloc(sizeof(PLine*) * lines_capacity);
|
||||||
size_t lines_size = 0;
|
size_t lines_size = 0;
|
||||||
@ -100,24 +110,47 @@ int main(int argc, char** argv)
|
|||||||
lines_capacity += 2;
|
lines_capacity += 2;
|
||||||
lines = realloc(lines, sizeof(PLine*) * lines_capacity);
|
lines = realloc(lines, sizeof(PLine*) * lines_capacity);
|
||||||
}
|
}
|
||||||
PLine* line = parser_next(&parser);
|
PStmt* stmt = parser_next_stmt(&parser);
|
||||||
if (!line) {
|
if (!stmt) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
lines[lines_size++] = line;
|
switch (stmt->ty) {
|
||||||
|
case PStmtTy_Line:
|
||||||
|
lines[lines_size++] = stmt->line;
|
||||||
|
// NOTE: Shallow free.
|
||||||
|
free(stmt);
|
||||||
|
break;
|
||||||
|
case PStmtTy_Global:
|
||||||
|
pstmt_free(stmt);
|
||||||
|
break;
|
||||||
|
case PStmtTy_Extern:
|
||||||
|
pstmt_free(stmt);
|
||||||
|
break;
|
||||||
|
case PStmtTy_Const: {
|
||||||
|
const IdentResol* existing
|
||||||
|
= ident_resolver_resolve(&resolver, stmt->ident);
|
||||||
|
if (existing != NULL) {
|
||||||
|
REPORTF_ERROR("redefinition of constant '%s'", stmt->ident);
|
||||||
|
reporter_print_loc(&rep, stmt->loc);
|
||||||
|
pstmt_free(stmt);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EvaledOperand evaled
|
||||||
|
= eval_operand_to_imm(&evaluator, stmt->value);
|
||||||
|
if (evaled.ty == EoTy_Err) {
|
||||||
|
pstmt_free(stmt);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ident_resolver_define_const(
|
||||||
|
&resolver, asm_strdup(stmt->ident), stmt->loc, evaled.imm);
|
||||||
|
pstmt_free(stmt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errors_occured &= parser_error_occured(&parser);
|
errors_occured &= parser_error_occured(&parser);
|
||||||
|
|
||||||
IdentResolver resolver;
|
|
||||||
ident_resolver_construct(&resolver);
|
|
||||||
|
|
||||||
OperandEvaluator evaluator = {
|
|
||||||
.re = &resolver,
|
|
||||||
.rep = &rep,
|
|
||||||
.second_pass = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t chunk_capacity = 64;
|
size_t chunk_capacity = 64;
|
||||||
uint16_t* chunk = malloc(sizeof(uint16_t) * chunk_capacity);
|
uint16_t* chunk = malloc(sizeof(uint16_t) * chunk_capacity);
|
||||||
|
|
||||||
|
118
asm/parse.c
118
asm/parse.c
@ -126,6 +126,26 @@ void pline_free(PLine* pline)
|
|||||||
free(pline);
|
free(pline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PStmt* pstmt_new_line(Loc loc, PLine* line)
|
||||||
|
{
|
||||||
|
PStmt* stmt = malloc(sizeof(PStmt));
|
||||||
|
*stmt = (PStmt) { .ty = PStmtTy_Line, .loc = loc, .line = line };
|
||||||
|
return stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
PStmt* pstmt_new_ident(PStmtTy ty, Loc loc, char* ident)
|
||||||
|
{
|
||||||
|
PStmt* stmt = malloc(sizeof(PStmt));
|
||||||
|
*stmt = (PStmt) { .ty = ty, .loc = loc, .ident = ident, .value = NULL };
|
||||||
|
return stmt;
|
||||||
|
}
|
||||||
|
PStmt* pstmt_new_const(PStmtTy ty, Loc loc, char* ident, POperand* value)
|
||||||
|
{
|
||||||
|
PStmt* stmt = malloc(sizeof(PStmt));
|
||||||
|
*stmt = (PStmt) { .ty = ty, .loc = loc, .ident = ident, .value = value };
|
||||||
|
return stmt;
|
||||||
|
}
|
||||||
|
|
||||||
void pstmt_free(PStmt* stmt)
|
void pstmt_free(PStmt* stmt)
|
||||||
{
|
{
|
||||||
switch (stmt->ty) {
|
switch (stmt->ty) {
|
||||||
@ -134,9 +154,12 @@ void pstmt_free(PStmt* stmt)
|
|||||||
break;
|
break;
|
||||||
case PStmtTy_Global:
|
case PStmtTy_Global:
|
||||||
case PStmtTy_Extern:
|
case PStmtTy_Extern:
|
||||||
case PStmtTy_Define:
|
|
||||||
free(stmt->ident);
|
free(stmt->ident);
|
||||||
break;
|
break;
|
||||||
|
case PStmtTy_Const:
|
||||||
|
free(stmt->ident);
|
||||||
|
poperand_free(stmt->value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free(stmt);
|
free(stmt);
|
||||||
}
|
}
|
||||||
@ -184,7 +207,7 @@ static inline bool parser_eat(Parser* parser, TokTy ty)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char* parser_ident_val(const Parser* parser, Tok tok)
|
static inline char* parser_text_val(const Parser* parser, Tok tok)
|
||||||
{
|
{
|
||||||
return asm_strndup(&parser->lexer.text[tok.loc.idx], tok.len);
|
return asm_strndup(&parser->lexer.text[tok.loc.idx], tok.len);
|
||||||
}
|
}
|
||||||
@ -218,7 +241,7 @@ static inline PLabel* parser_parse_labels(
|
|||||||
plabel_free(labels);
|
plabel_free(labels);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
char* label_ident = parser_ident_val(parser, parser->eaten);
|
char* label_ident = parser_text_val(parser, parser->eaten);
|
||||||
if (!parser_eat(parser, ':')) {
|
if (!parser_eat(parser, ':')) {
|
||||||
parser_report(parser, "expected ':'", parser->tok.loc);
|
parser_report(parser, "expected ':'", parser->tok.loc);
|
||||||
plabel_free(labels);
|
plabel_free(labels);
|
||||||
@ -227,7 +250,7 @@ static inline PLabel* parser_parse_labels(
|
|||||||
}
|
}
|
||||||
labels = plabel_new(labels, label_ident, true, loc);
|
labels = plabel_new(labels, label_ident, true, loc);
|
||||||
} else if (parser_eat(parser, TT_Ident)) {
|
} else if (parser_eat(parser, TT_Ident)) {
|
||||||
*ident = parser_ident_val(parser, parser->eaten);
|
*ident = parser_text_val(parser, parser->eaten);
|
||||||
*ident_loc = loc;
|
*ident_loc = loc;
|
||||||
if (!parser_eat(parser, ':')) {
|
if (!parser_eat(parser, ':')) {
|
||||||
break;
|
break;
|
||||||
@ -269,7 +292,7 @@ static inline POperand* parser_parse_operand_0(Parser* parser)
|
|||||||
{
|
{
|
||||||
Loc loc = parser->tok.loc;
|
Loc loc = parser->tok.loc;
|
||||||
if (parser_eat(parser, TT_Ident)) {
|
if (parser_eat(parser, TT_Ident)) {
|
||||||
char* ident = parser_ident_val(parser, parser->eaten);
|
char* ident = parser_text_val(parser, parser->eaten);
|
||||||
const char* reg_key[10] = {
|
const char* reg_key[10] = {
|
||||||
"r0", "r1", "r2", "r3", "r4", "rbp", "rsp", "rfl", "rcs", "rip"
|
"r0", "r1", "r2", "r3", "r4", "rbp", "rsp", "rfl", "rcs", "rip"
|
||||||
};
|
};
|
||||||
@ -282,7 +305,7 @@ static inline POperand* parser_parse_operand_0(Parser* parser)
|
|||||||
}
|
}
|
||||||
return poperand_new_str(PoTy_Ident, ident, parser->eaten.len, loc);
|
return poperand_new_str(PoTy_Ident, ident, parser->eaten.len, loc);
|
||||||
} else if (parser_eat(parser, TT_Int)) {
|
} else if (parser_eat(parser, TT_Int)) {
|
||||||
char* str = parser_ident_val(parser, parser->eaten);
|
char* str = parser_text_val(parser, parser->eaten);
|
||||||
uint64_t val = strtoull(str, NULL, 10);
|
uint64_t val = strtoull(str, NULL, 10);
|
||||||
free(str);
|
free(str);
|
||||||
if (val > 0xffff) {
|
if (val > 0xffff) {
|
||||||
@ -294,7 +317,7 @@ static inline POperand* parser_parse_operand_0(Parser* parser)
|
|||||||
uint16_t imm = (uint16_t)val;
|
uint16_t imm = (uint16_t)val;
|
||||||
return poperand_new_imm(imm, loc);
|
return poperand_new_imm(imm, loc);
|
||||||
} else if (parser_eat(parser, TT_Binary)) {
|
} else if (parser_eat(parser, TT_Binary)) {
|
||||||
char* str = parser_ident_val(parser, parser->eaten);
|
char* str = parser_text_val(parser, parser->eaten);
|
||||||
uint64_t val = strtoull(&str[2], NULL, 2);
|
uint64_t val = strtoull(&str[2], NULL, 2);
|
||||||
free(str);
|
free(str);
|
||||||
if (val > 0xffff) {
|
if (val > 0xffff) {
|
||||||
@ -306,7 +329,7 @@ static inline POperand* parser_parse_operand_0(Parser* parser)
|
|||||||
uint16_t imm = (uint16_t)val;
|
uint16_t imm = (uint16_t)val;
|
||||||
return poperand_new_imm(imm, loc);
|
return poperand_new_imm(imm, loc);
|
||||||
} else if (parser_eat(parser, TT_Hex)) {
|
} else if (parser_eat(parser, TT_Hex)) {
|
||||||
char* str = parser_ident_val(parser, parser->eaten);
|
char* str = parser_text_val(parser, parser->eaten);
|
||||||
uint64_t val = strtoull(&str[2], NULL, 16);
|
uint64_t val = strtoull(&str[2], NULL, 16);
|
||||||
free(str);
|
free(str);
|
||||||
if (val > 0xffff) {
|
if (val > 0xffff) {
|
||||||
@ -318,12 +341,12 @@ static inline POperand* parser_parse_operand_0(Parser* parser)
|
|||||||
uint16_t imm = (uint16_t)val;
|
uint16_t imm = (uint16_t)val;
|
||||||
return poperand_new_imm(imm, loc);
|
return poperand_new_imm(imm, loc);
|
||||||
} else if (parser_eat(parser, TT_Char)) {
|
} else if (parser_eat(parser, TT_Char)) {
|
||||||
char* str = parser_ident_val(parser, parser->eaten);
|
char* str = parser_text_val(parser, parser->eaten);
|
||||||
uint16_t imm = (uint16_t)literal_char_val(&str[1]);
|
uint16_t imm = (uint16_t)literal_char_val(&str[1]);
|
||||||
free(str);
|
free(str);
|
||||||
return poperand_new_imm(imm, loc);
|
return poperand_new_imm(imm, loc);
|
||||||
} else if (parser_eat(parser, TT_Str)) {
|
} else if (parser_eat(parser, TT_Str)) {
|
||||||
char* lit = parser_ident_val(parser, parser->eaten);
|
char* lit = parser_text_val(parser, parser->eaten);
|
||||||
size_t lit_len = strlen(lit);
|
size_t lit_len = strlen(lit);
|
||||||
char* str = calloc(lit_len - 1, sizeof(char));
|
char* str = calloc(lit_len - 1, sizeof(char));
|
||||||
size_t str_len = 0;
|
size_t str_len = 0;
|
||||||
@ -337,7 +360,7 @@ static inline POperand* parser_parse_operand_0(Parser* parser)
|
|||||||
parser_report(parser, "expected identifier", parser->tok.loc);
|
parser_report(parser, "expected identifier", parser->tok.loc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
char* ident = parser_ident_val(parser, parser->eaten);
|
char* ident = parser_text_val(parser, parser->eaten);
|
||||||
return poperand_new_str(PoTy_SubLabel, ident, parser->eaten.len, loc);
|
return poperand_new_str(PoTy_SubLabel, ident, parser->eaten.len, loc);
|
||||||
} else if (parser_eat(parser, '(')) {
|
} else if (parser_eat(parser, '(')) {
|
||||||
POperand* operand = parser_parse_operand_2(parser, parser_binary_prec);
|
POperand* operand = parser_parse_operand_2(parser, parser_binary_prec);
|
||||||
@ -431,7 +454,7 @@ static inline POperand* parser_parse_operand_3(Parser* parser)
|
|||||||
if (!parser_test(parser, TT_Ident)) {
|
if (!parser_test(parser, TT_Ident)) {
|
||||||
return parser_parse_operand_2(parser, parser_binary_prec);
|
return parser_parse_operand_2(parser, parser_binary_prec);
|
||||||
}
|
}
|
||||||
char* ident = parser_ident_val(parser, parser->tok);
|
char* ident = parser_text_val(parser, parser->tok);
|
||||||
if (strcmp(ident, "u8") == 0) {
|
if (strcmp(ident, "u8") == 0) {
|
||||||
free(ident);
|
free(ident);
|
||||||
parser_step(parser);
|
parser_step(parser);
|
||||||
@ -473,15 +496,14 @@ static inline void parser_skip_to_next_line(Parser* parser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PLine* parser_next(Parser* parser)
|
PLine* parser_next_line(Parser* parser)
|
||||||
{
|
{
|
||||||
char* ident;
|
char* ident;
|
||||||
Loc loc;
|
Loc loc;
|
||||||
PLabel* labels = parser_parse_labels(parser, &ident, &loc);
|
PLabel* labels = parser_parse_labels(parser, &ident, &loc);
|
||||||
|
|
||||||
const size_t max_ops_size = 64;
|
const size_t max_ops_size = 64;
|
||||||
// TODO: Move allocation out-of-band.
|
POperand* ops[64];
|
||||||
POperand** ops = malloc(sizeof(POperand) * max_ops_size);
|
|
||||||
size_t ops_size = 0;
|
size_t ops_size = 0;
|
||||||
|
|
||||||
if (!parser_test(parser, TT_Eof) && !parser_test(parser, '\n')) {
|
if (!parser_test(parser, TT_Eof) && !parser_test(parser, '\n')) {
|
||||||
@ -520,15 +542,77 @@ PLine* parser_next(Parser* parser)
|
|||||||
parser_skip_newlines(parser);
|
parser_skip_newlines(parser);
|
||||||
|
|
||||||
PLine* line = pline_new(ident, labels, loc, ops_size, ops);
|
PLine* line = pline_new(ident, labels, loc, ops_size, ops);
|
||||||
free(ops);
|
|
||||||
return line;
|
return line;
|
||||||
|
|
||||||
error_free_ops:
|
error_free_ops:
|
||||||
for (size_t i = 0; i < ops_size; ++i)
|
for (size_t i = 0; i < ops_size; ++i)
|
||||||
if (ops[i])
|
if (ops[i])
|
||||||
poperand_free(ops[i]);
|
poperand_free(ops[i]);
|
||||||
free(ops);
|
|
||||||
plabel_free(labels);
|
plabel_free(labels);
|
||||||
free(ident);
|
free(ident);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline PStmtTy pstmt_keyword_ty(const char* ident)
|
||||||
|
{
|
||||||
|
const PStmtTy tys[] = {
|
||||||
|
PStmtTy_Global,
|
||||||
|
PStmtTy_Extern,
|
||||||
|
PStmtTy_Const,
|
||||||
|
};
|
||||||
|
const char* keywords[] = {
|
||||||
|
"global",
|
||||||
|
"extern",
|
||||||
|
"const",
|
||||||
|
};
|
||||||
|
static_assert(
|
||||||
|
sizeof(keywords) / sizeof(keywords[0]) == sizeof(tys) / sizeof(tys[0]),
|
||||||
|
"mismatch");
|
||||||
|
|
||||||
|
size_t amount = sizeof(tys) / sizeof(tys[0]);
|
||||||
|
for (size_t i = 0; i < amount; ++i) {
|
||||||
|
if (strcmp(ident, keywords[i]) == 0) {
|
||||||
|
return tys[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PStmtTy_Line;
|
||||||
|
}
|
||||||
|
|
||||||
|
PStmt* parser_next_stmt(Parser* parser)
|
||||||
|
{
|
||||||
|
parser_skip_newlines(parser);
|
||||||
|
Loc loc = parser->tok.loc;
|
||||||
|
if (!parser_test(parser, TT_Ident)) {
|
||||||
|
PLine* line = parser_next_line(parser);
|
||||||
|
if (!line)
|
||||||
|
return NULL;
|
||||||
|
return pstmt_new_line(loc, line);
|
||||||
|
}
|
||||||
|
char* keyword = parser_text_val(parser, parser->tok);
|
||||||
|
PStmtTy ty = pstmt_keyword_ty(keyword);
|
||||||
|
free(keyword);
|
||||||
|
switch (ty) {
|
||||||
|
case PStmtTy_Global:
|
||||||
|
case PStmtTy_Extern:
|
||||||
|
case PStmtTy_Const: {
|
||||||
|
parser_step(parser);
|
||||||
|
if (!parser_eat(parser, TT_Ident)) {
|
||||||
|
parser_report(parser, "expected identifier", parser->tok.loc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char* ident = parser_text_val(parser, parser->eaten);
|
||||||
|
if (ty != PStmtTy_Const) {
|
||||||
|
return pstmt_new_ident(ty, loc, ident);
|
||||||
|
}
|
||||||
|
POperand* value = parser_parse_operand_3(parser);
|
||||||
|
return pstmt_new_const(ty, loc, ident, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PLine* line = parser_next_line(parser);
|
||||||
|
if (!line)
|
||||||
|
return NULL;
|
||||||
|
return pstmt_new_line(loc, line);
|
||||||
|
}
|
||||||
|
14
asm/parse.h
14
asm/parse.h
@ -84,17 +84,24 @@ typedef enum {
|
|||||||
PStmtTy_Line,
|
PStmtTy_Line,
|
||||||
PStmtTy_Global,
|
PStmtTy_Global,
|
||||||
PStmtTy_Extern,
|
PStmtTy_Extern,
|
||||||
PStmtTy_Define,
|
PStmtTy_Const,
|
||||||
} PStmtTy;
|
} PStmtTy;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PStmtTy ty;
|
PStmtTy ty;
|
||||||
|
Loc loc;
|
||||||
union {
|
union {
|
||||||
PLine* line;
|
PLine* line;
|
||||||
char* ident;
|
struct {
|
||||||
|
char* ident;
|
||||||
|
POperand* value;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
} PStmt;
|
} PStmt;
|
||||||
|
|
||||||
|
PStmt* pstmt_new_line(Loc loc, PLine* line);
|
||||||
|
PStmt* pstmt_new_ident(PStmtTy ty, Loc loc, char* ident);
|
||||||
|
PStmt* pstmt_new_const(PStmtTy ty, Loc loc, char* ident, POperand* value);
|
||||||
void pstmt_free(PStmt* stmt);
|
void pstmt_free(PStmt* stmt);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -107,4 +114,5 @@ typedef struct {
|
|||||||
void parser_construct(Parser* parser, const char* filename, const char* text);
|
void parser_construct(Parser* parser, const char* filename, const char* text);
|
||||||
bool parser_done(const Parser* parser);
|
bool parser_done(const Parser* parser);
|
||||||
bool parser_error_occured(const Parser* parser);
|
bool parser_error_occured(const Parser* parser);
|
||||||
PLine* parser_next(Parser* parser);
|
PLine* parser_next_line(Parser* parser);
|
||||||
|
PStmt* parser_next_stmt(Parser* parser);
|
||||||
|
@ -9,6 +9,7 @@ void ident_resol_destroy(IdentResol* resol)
|
|||||||
break;
|
break;
|
||||||
case IdentResolTy_Label:
|
case IdentResolTy_Label:
|
||||||
case IdentResolTy_SubLabel:
|
case IdentResolTy_SubLabel:
|
||||||
|
case IdentResolTy_Const:
|
||||||
free(resol->ident);
|
free(resol->ident);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -77,6 +78,18 @@ void ident_resolver_define_sublabel(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ident_resolver_define_const(
|
||||||
|
IdentResolver* resolver, char* ident, Loc loc, uint16_t value)
|
||||||
|
{
|
||||||
|
size_t i = ident_resolver_first_empty(resolver);
|
||||||
|
resolver->resols[i] = (IdentResol) {
|
||||||
|
.ident = ident,
|
||||||
|
.loc = loc,
|
||||||
|
.ty = IdentResolTy_Const,
|
||||||
|
.value = value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const IdentResol* ident_resolver_resolve(
|
const IdentResol* ident_resolver_resolve(
|
||||||
const IdentResolver* resolver, const char* ident)
|
const IdentResolver* resolver, const char* ident)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ typedef enum {
|
|||||||
IdentResolTy_None,
|
IdentResolTy_None,
|
||||||
IdentResolTy_Label,
|
IdentResolTy_Label,
|
||||||
IdentResolTy_SubLabel,
|
IdentResolTy_SubLabel,
|
||||||
|
IdentResolTy_Const,
|
||||||
} IdentResolTy;
|
} IdentResolTy;
|
||||||
|
|
||||||
typedef struct IdentResol IdentResol;
|
typedef struct IdentResol IdentResol;
|
||||||
@ -17,6 +18,7 @@ struct IdentResol {
|
|||||||
IdentResolTy ty;
|
IdentResolTy ty;
|
||||||
union {
|
union {
|
||||||
uint16_t ip;
|
uint16_t ip;
|
||||||
|
uint16_t value;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,5 +38,7 @@ void ident_resolver_define_label(
|
|||||||
IdentResolver* resolver, char* ident, Loc loc, uint16_t asm_ip);
|
IdentResolver* resolver, char* ident, Loc loc, uint16_t asm_ip);
|
||||||
void ident_resolver_define_sublabel(
|
void ident_resolver_define_sublabel(
|
||||||
IdentResolver* resolver, char* ident, Loc loc, uint16_t asm_ip);
|
IdentResolver* resolver, char* ident, Loc loc, uint16_t asm_ip);
|
||||||
|
void ident_resolver_define_const(
|
||||||
|
IdentResolver* resolver, char* ident, Loc loc, uint16_t value);
|
||||||
const IdentResol* ident_resolver_resolve(
|
const IdentResol* ident_resolver_resolve(
|
||||||
const IdentResolver* resolver, const char* ident);
|
const IdentResolver* resolver, const char* ident);
|
||||||
|
@ -1,17 +1,41 @@
|
|||||||
|
|
||||||
|
const Fl_Zero 0
|
||||||
|
const Fl_Eq 1
|
||||||
|
const Fl_Be 2
|
||||||
|
const Fl_Lt 3
|
||||||
|
const Fl_Err 4
|
||||||
|
const Fl_Int 5
|
||||||
|
const Fl_Vcd 6
|
||||||
|
|
||||||
|
const Int_DiskRead 0
|
||||||
|
const Int_DiskWrite 1
|
||||||
|
const Int_Key 32
|
||||||
|
|
||||||
|
const Device_Keyboard 0
|
||||||
|
|
||||||
|
const vcd_ch_width 8
|
||||||
|
const vcd_ch_height 8
|
||||||
|
const vcd_width_in_ch 40
|
||||||
|
const vcd_height_in_ch 12
|
||||||
|
|
||||||
|
const vcd_px_width 4
|
||||||
|
const vcd_px_height 8
|
||||||
|
const vcd_width_in_px vcd_width_in_ch * vcd_ch_width * vcd_px_width
|
||||||
|
const vcd_height_in_px vcd_height_in_ch * vcd_ch_height * vcd_px_height
|
||||||
|
|
||||||
start:
|
start:
|
||||||
; rsp points *at* the top element
|
; rsp points *at* the top element
|
||||||
mov rbp, 2048
|
mov rbp, 2048
|
||||||
mov rsp, 2048 - 2
|
mov rsp, 2048 - 2
|
||||||
|
|
||||||
lit interrupt_table
|
lit interrupt_table
|
||||||
or rfl, rfl, 1 << 5 ; Fl_Int
|
or rfl, rfl, 1 << Fl_Int
|
||||||
|
|
||||||
or rfl, rfl, 1 << 6 ; Fl_Vcd
|
or rfl, rfl, 1 << Fl_Vcd
|
||||||
|
|
||||||
mov r0, 512
|
mov r0, 512
|
||||||
mov r1, 1
|
mov r1, 1
|
||||||
int 0 ; Int_DiskRead
|
int Int_DiskRead
|
||||||
|
|
||||||
main_loop:
|
main_loop:
|
||||||
hlt
|
hlt
|
||||||
@ -24,7 +48,7 @@ interrupt_table:
|
|||||||
nop
|
nop
|
||||||
|
|
||||||
keyboard_interrupt:
|
keyboard_interrupt:
|
||||||
and rfl, rfl, !(1 << 5) ; Fl_Int
|
and rfl, rfl, !(1 << Fl_Int)
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
push r0
|
push r0
|
||||||
@ -32,21 +56,21 @@ keyboard_interrupt:
|
|||||||
push r2
|
push r2
|
||||||
push r3
|
push r3
|
||||||
|
|
||||||
in r0, 0 ; Device_Keyboard
|
in r0, Device_Keyboard
|
||||||
|
|
||||||
cmp r0, 44
|
cmp r0, 44
|
||||||
mov r1, rfl
|
mov r1, rfl
|
||||||
and r1, r1, 1 << 1 ; Fl_Eq
|
and r1, r1, 1 << Fl_Eq
|
||||||
jnz r1, .L0
|
jnz r1, .L0
|
||||||
|
|
||||||
cmp r0, 42
|
cmp r0, 42
|
||||||
mov r1, rfl
|
mov r1, rfl
|
||||||
and r1, r1, 1 << 1 ; Fl_Eq
|
and r1, r1, 1 << Fl_Eq
|
||||||
jnz r1, .L1
|
jnz r1, .L1
|
||||||
|
|
||||||
cmp r0, 40
|
cmp r0, 40
|
||||||
mov r1, rfl
|
mov r1, rfl
|
||||||
and r1, r1, 1 << 1 ; Fl_Eq
|
and r1, r1, 1 << Fl_Eq
|
||||||
jnz r1, .L2
|
jnz r1, .L2
|
||||||
|
|
||||||
jmp .L3
|
jmp .L3
|
||||||
@ -60,7 +84,7 @@ keyboard_interrupt:
|
|||||||
mov r1, u16 [screen_x]
|
mov r1, u16 [screen_x]
|
||||||
cmp r1, 0
|
cmp r1, 0
|
||||||
mov r2, rfl
|
mov r2, rfl
|
||||||
and r2, r2, 1 << 1 ; Fl_Eq
|
and r2, r2, 1 << Fl_Eq
|
||||||
jnz r2, .L4
|
jnz r2, .L4
|
||||||
sub r1, r1, 1
|
sub r1, r1, 1
|
||||||
mov u16 [screen_x], r1
|
mov u16 [screen_x], r1
|
||||||
@ -92,7 +116,7 @@ keyboard_interrupt:
|
|||||||
pop r0
|
pop r0
|
||||||
mov rsp, rbp
|
mov rsp, rbp
|
||||||
pop rbp
|
pop rbp
|
||||||
or rfl, rfl, 1 << 5 ; Fl_Int
|
or rfl, rfl, 1 << Fl_Int
|
||||||
iret
|
iret
|
||||||
|
|
||||||
put_char:
|
put_char:
|
||||||
@ -102,7 +126,7 @@ put_char:
|
|||||||
push r2
|
push r2
|
||||||
|
|
||||||
mov r2, u16 [screen_y]
|
mov r2, u16 [screen_y]
|
||||||
mul r2, r2, 40 ; vcd_width_in_ch
|
mul r2, r2, vcd_width_in_ch
|
||||||
mov r1, u16 [screen_x]
|
mov r1, u16 [screen_x]
|
||||||
add r1, r1, 0x0c00
|
add r1, r1, 0x0c00
|
||||||
add r1, r1, r2
|
add r1, r1, r2
|
||||||
@ -112,9 +136,9 @@ put_char:
|
|||||||
add r1, r1, 1
|
add r1, r1, 1
|
||||||
mov u16 [screen_x], r1
|
mov u16 [screen_x], r1
|
||||||
|
|
||||||
cmp r1, 40 ; vcd_width_in_ch
|
cmp r1, vcd_width_in_ch
|
||||||
mov r2, rfl
|
mov r2, rfl
|
||||||
and r2, r2, 1 << 1 ; Fl_Eq
|
and r2, r2, 1 << Fl_Eq
|
||||||
jnz r2, .L0
|
jnz r2, .L0
|
||||||
jmp .L1
|
jmp .L1
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user