s502 assembler
A very simple assembler for the 6502 line of processors written in C
pass_twothree.c
Go to the documentation of this file.
1 #include "debugmalloc.h"
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <string.h>
7 
8 #include "state.h"
9 #include "pass_twothree.h"
10 #include "tokenFunc.h"
11 #include "logging.h"
12 
19 int pass_two(State* s) {
20  for (TokensListElement* ptr = s->tokens->head; ptr != NULL; ptr = ptr->next) {
21  int ret = token_get_operand(s, ptr->token);
22  if (ret < 0 || (ptr->token->type == TT_INSTR && (ptr->token->instr.number < 0))) {
23  if (ret == 0) {
24  ERROR("Undefined label reference!\n");
25  }
26  token_print(ptr->token);
27  FAIL("Pass two failed!\n");
28  return -1;
29  }
30  }
31  return 0;
32 }
33 
42 char* concat_bin(State* s, int* n) {
43  // count len
44  int len = 0;
45  for (TokensListElement* ptr = s->tokens->head; ptr != NULL; ptr = ptr->next) len += ptr->token->binSize;
46  *n = len;
47 
48  // alloc & fill buffer
49  char* data = malloc(len);
50  int j = 0;
51  for (TokensListElement* ptr = s->tokens->head; ptr != NULL; ptr = ptr->next) {
52  char* tdata;
53  int n = token_compile(s, ptr->token, &tdata);
54  if (n < 0) {
55  // some error happened
56  free(data);
57  free(tdata);
58  return NULL;
59  }
60  // write data
61  for (int i = 0; i < ptr->token->binSize; i++) data[j + i] = tdata[i];
62  j += ptr->token->binSize;
63  free(tdata);
64  }
65 
66  return data;
67 }
68 
69 int write_data(State* s) {
70  // first concat, then write
71  // this way we only write (and destroy possible prev. file) if we can do that
72  int l;
73  char* data = concat_bin(s, &l);
74  if (!data) {
75  FAIL("Could not compile data!\n");
76  return -1;
77  }
78 
79  FILE* f = fopen(s->outfile, "wb");
80  if (!f) {
81  ERROR("An error occured opening the file %s!\n", s->outfile);
82  ERROR("Error opening file: %s\n", strerror(errno));
83  free(data);
84  return -1;
85  }
86  fwrite(data, 1, l, f);
87  free(data);
88  fclose(f);
89  return 0;
90 }
TT_INSTR
@ TT_INSTR
instruction token
Definition: token_t.h:26
pass_two
int pass_two(State *s)
compilation pass 2
Definition: pass_twothree.c:19
pass_twothree.h
processing steps 2 and 3
State::tokens
TokensList * tokens
tokens
Definition: state.h:38
State
Compiler pseudo-global state.
Definition: state.h:32
TokensListElement::next
struct TokensListElement * next
next element in list or NULL
Definition: tokenslist.h:20
State::outfile
char outfile[STATE_MAX_STRING_LEN]
output file name
Definition: state.h:46
TokensList::head
TokensListElement * head
head (first element) of the list
Definition: tokenslist.h:31
TokensListElement
An element of a TokensList.
Definition: tokenslist.h:16
concat_bin
char * concat_bin(State *s, int *n)
compile tokens and concat binary data
Definition: pass_twothree.c:42
write_data
int write_data(State *s)
compilation pass 3
Definition: pass_twothree.c:69
tokenFunc.h
Token type member methods.
Token::token_print
void token_print(Token *token)
Pretty-print one token, with its source and length.
Definition: tokenFunc.c:20
Token::token_compile
int token_compile(State *s, Token *t, char **dataptr)
compile token into binary data
Definition: tokenFunc.c:318
logging.h
logging and fancy-printing
Token::token_get_operand
int token_get_operand(State *s, Token *t)
parse the operand of the instruction as a number
Definition: tokenFunc.c:287
state.h
implement State class
FAIL
#define FAIL(...)
Fancy-print a fail (failed step). Works like printf.
Definition: logging.h:45
ERROR
#define ERROR(...)
Fancy-print an error (cause of faliure). Works like printf.
Definition: logging.h:40