• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

MOT6502 assembler, disassembler and linker


Commit MetaInfo

修订版4d828c8878ac64dfaab024b72c18fc8087a18e2e (tree)
时间2013-02-08 20:21:00
作者astoria-d <astoria-d@my-s...>
Commiterastoria-d

Log Message

assembler addressing mode fix.
now hello world assembler is verified.

更改概述

差异

--- a/assembler/6502inst.c
+++ b/assembler/6502inst.c
@@ -17,6 +17,8 @@ struct instmap {
1717 #define NUM_ALPHA 'Z' - 'A' + 1
1818 #define ALPHA_INDEX(ch) ch - 'A'
1919
20+#define ROM_START 0x8000
21+
2022 /*
2123 * 6502 instructions
2224 * adressing mode instruction length
@@ -128,6 +130,10 @@ int get_rel_addr(unsigned short abs_addr) {
128130 return (int) abs_addr - get_current_pc() ;
129131 }
130132
133+int get_abs_addr(unsigned short abs_addr) {
134+ return (int) abs_addr + ROM_START ;
135+}
136+
131137 /*
132138 * returns the length of opcode.
133139 * returns 0 if invalid.
@@ -388,11 +394,13 @@ static void deb_print_str(const char* str) {
388394 }
389395
390396 void write_str(const char* str) {
397+ //dprint("write_str:%s\n", str);
391398 int len = strlen(str) + 1;
392399 FILE* fp = get_current_file();
400+ char* p = str;
393401 while (len-- > 0)
394402 fwrite(str++, 1, 1, fp);
395- deb_print_str(str);
403+ deb_print_str(p);
396404 move_current_pc(len);
397405 }
398406
--- a/assembler/nesas.y
+++ b/assembler/nesas.y
@@ -15,6 +15,7 @@ char* cur_inst;
1515 int dir_data_size = 0;
1616
1717 void add_unresolved_ref(const char* symbol);
18+int get_abs_addr(unsigned short abs_addr);
1819
1920 #if 1
2021 #define dprint(...)
@@ -205,6 +206,12 @@ inst_param
205206 unsigned short addr = 0;
206207 int num = 0;
207208
209+
210+ /*
211+ ex)
212+ lda palettes, x
213+ */
214+
208215 //second parameter is either X or Y.
209216 if (strcasecmp($<str>3, "X") && strcasecmp($<str>3, "Y")) {
210217 parser_perror("invalid parameter\n", $<str>3);
@@ -218,11 +225,13 @@ inst_param
218225 param = PARAM_NUM;
219226 ch = toupper(*$<str>3);
220227 param |= (ch == 'X' ? PARAM_INDEX_X : PARAM_INDEX_Y);
221- if (addr_lookup($<str>1, &addr))
222- num = get_rel_addr(addr);
228+ if (addr_lookup($<str>1, &addr)) {
229+ //reladdr from the next instruction.
230+ num = get_rel_addr(addr) - 2;
231+ }
223232 else {
224233 add_unresolved_ref($<str>1);
225- num = addr;
234+ num = 0xFFFF;
226235 }
227236
228237 if (!write_inst(cur_inst, param, num)) {
@@ -288,12 +297,28 @@ inst_param
288297 unsigned short addr = 0;
289298 int num = 0;
290299
300+ /*
301+ ex)
302+ mainloop:
303+ jmp mainloop
304+ bne mainloop
305+ */
306+
291307 dprint("%s\n", $<str>1);
292- if (addr_lookup($<str>1, &addr))
293- num = get_rel_addr(addr);
308+ if (addr_lookup($<str>1, &addr)) {
309+ //set operand assocating with the instruction's addressing mode
310+ //(relative or absolute).
311+ if (!strcasecmp(cur_inst, "JMP") || !strcasecmp(cur_inst, "JSR")) {
312+ num = get_abs_addr(addr);
313+ }
314+ else {
315+ //reladdr from the next instruction.
316+ num = get_rel_addr(addr) - 2;
317+ }
318+ }
294319 else {
295320 add_unresolved_ref($<str>1);
296- num = addr;
321+ num = 0xFFFF;
297322 }
298323
299324 if (!write_inst(cur_inst, PARAM_NUM, num)) {
--- a/assembler/segment.c
+++ b/assembler/segment.c
@@ -24,6 +24,7 @@ const char* get_out_fname(void);
2424 void molf_header_create(FILE* fp, unsigned short seg_cnt);
2525 void seg_header_create(FILE* fp, struct seginfo* seg);
2626 int set_seg_header_pos(FILE* fp, struct seginfo* seg, unsigned short start);
27+int get_abs_addr(unsigned short abs_addr);
2728
2829 int add_symbol (const char* symbol) {
2930 struct symmap *psym, *pp;
@@ -70,7 +71,9 @@ void add_unresolved_ref(const char* symbol) {
7071 unres_sym = malloc(sizeof (struct symmap));
7172 dlist_init(&unres_sym->list);
7273 unres_sym->symbol = strdup(symbol);
73- unres_sym->addr = pseg->current_pc;
74+ //current_pc points to the current instruction.
75+ //referece is next to the pc
76+ unres_sym->addr = pseg->current_pc + 1;
7477
7578 if (pseg->unresolved_symbol == NULL) {
7679 pseg->unresolved_symbol = unres_sym;
@@ -91,6 +94,8 @@ int addr_lookup(const char* symbol, unsigned short* return_addr) {
9194 struct symmap* pp = psym;
9295
9396 if (!strcmp(symbol, psym->symbol)) {
97+ dprint("addr_lookup %s found %04x, current:%08x\n", psym->symbol,
98+ psym->addr, get_current_pc());
9499 found = TRUE;
95100 *return_addr = psym->addr;
96101 break;
@@ -257,9 +262,10 @@ int finalize_segment(void) {
257262 //address offset is too far!
258263 return FALSE;
259264 }
260- /*dprint("symbol ref at %04x to %s(%04x) resolved, %04x.\n",
261- unres->addr, unres->symbol, addr, addr - unres->addr);*/
262- fseek(fp, addr - unres->addr, SEEK_SET);
265+ addr = get_abs_addr(addr);
266+ dprint("symbol ref at %04x to %s resolved, %04x.\n",
267+ unres->addr, unres->symbol, addr);/**/
268+ fseek(fp, unres->addr, SEEK_SET);
263269 fwrite(&addr, 2, 1, fp);
264270 }
265271 unres = (struct symmap*) unres->list.next;