home *** CD-ROM | disk | FTP | other *** search
-
- /* Assembler for the HuC6280 microprocessor found in the PC Engine console.
- * ----
- * This program was originaly a 6502 assembler written by
- * J. H. Van Ornum, it has been modified by David Michel
- * to support the HuC6280.
- *
- * This program is freeware. You are free to distribute, use and
- * modifiy it as you wish.
- *
- * Enjoy!
- */
-
- #include <stdio.h>
- #include <string.h>
- #include "defs.h"
- #include "externs.h"
- #include "vars.h"
-
- /***** DEFINES *************/
-
- /***** GLOBALS *************/
-
- int infile_error;
- int infile_num;
- int switch_throwback;
- char i_file[128];
- char o_file[128];
- char l_file[128];
- FILE *iptr;
- FILE *optr;
- FILE *lptr;
- struct t_input_info input_file[8];
- /*----------------*/
-
- int field[] = {
- SFIELD,
- SFIELD + 8,
- SFIELD + 14,
- SFIELD + 14,
- SFIELD + 14,
- SFIELD + 14,
- /* SFIELD + 23, */
- /* SFIELD + 43, */
- /* SFIELD + 75 */
- };
-
- /***** EXTERNALS ***********/
-
- /*
- * main :
- * -----
- *
- */
-
- main(int argc, char **argv)
- {
- char *p;
- int i, usage = 1;
-
- i_file[0] = o_file[0] = l_file[0] = 0;
- switch_throwback = 0;
- for (i = 1; i < argc && usage; i++) {
- if (!strcmp(argv[i], "-o")) strcpy(o_file, argv[++i]);
- else if (!strcmp(argv[i], "-throwback")) switch_throwback = 1;
- else if (argv[i][0] != '-') {
- if (i_file[0] == 0) strcpy(i_file, argv[i]);
- else if (l_file[0] == 0) strcpy(l_file, argv[i]);
- else usage = 0;
- }
- else usage = 0;
- }
- if (usage == 0 || o_file[0] == 0 || i_file[0] == 0) {
- fprintf(stderr, "Syntax: magicasm <source file> -o <output file> [-throwback] [<list file>]\n");
- return(1);
- }
- if (l_file[0] == 0) strcpy(l_file, "null:$.l_file");
-
- /* -- auto-add the file extensions. */
-
- /* strupr(i_file);*/
-
- /* if (p = strrchr(i_file, '.')) {
- if (!strchr(p, '\\'))
- *p = '\0';
- else
- p = NULL;
- }
-
- strcpy(o_file, i_file);
- strcpy(l_file, i_file);
- strcat(o_file, ".PCE");
- strcat(l_file, ".LST");
-
- if (p)
- *p = '.';
- else
- strcat(i_file, ".ASM");*/
-
- /* -- open the input file. */
-
- if (open_input(i_file)) {
- fprintf(stdout, "Can not open input file '%s'!\n", i_file);
- exit(1);
- }
-
- /* -- clear the code array. */
-
- memset(rom, 8192 * 128, 0);
-
- /* -- assemble. */
-
- for (i = 0; i < 256; i++) {
- hash_tbl[i] = NULL;
- macro_tbl[i] = NULL;
- }
-
- for (pass = FIRST_PASS; pass <= LAST_PASS; pass++) {
- infile_error = -1;
- errcnt = 0;
- page = 0;
- bank = 0;
- max_bank = 0;
- loccnt = 0;
- slnum = 0;
- mcounter = 0;
- mcntmax = 0;
- clist = 0;
- mlist = 0;
- glablptr = NULL;
- rsbase = 0;
-
- for (i = 0; i < 128; i++) {
- bank_offset[i] = 0;
- bank_page[i] = 0;
- }
- while (readline() != -1) {
- assemble();
- if (loccnt > 0x2000) {
- error("Out of range, bank offset > $1FFF!");
- break;
- }
- }
- if (errcnt) {
- if (switch_throwback == 2) {
- DDEUtils_ThrowbackEnd();
- switch_throwback = 1;
- }
- fprintf(stdout, "# %d ERROR(s)\n", errcnt);
- break;
- }
-
- rewind(iptr);
-
- if (pass == FIRST_PASS) {
- if (xlist) {
- if ((lptr = fopen(l_file, "w")) == NULL) {
- fprintf(stdout, "Can not open listing file '%s'!\n", l_file);
- exit(1);
- }
- fprintf(lptr, "#[1] %s\n", input_file[1].name);
- }
- }
- }
-
- if (errcnt == 0) {
- if ((optr = fopen(o_file, "wb")) == NULL) {
- fprintf(stdout, "Can not open object file '%s'!\n", o_file);
- exit(1);
- }
- fwrite(rom, 8192, max_bank + 1, optr);
- fclose(optr);
- }
- if (xlist)
- fclose(lptr);
- fclose(iptr);
- return(0);
- }
-
- /*
- * readline :
- * ---------
- * reads and formats an input line.
- *
- */
-
- readline()
- {
- char *ptr, *arg, num[8];
- int j, n;
- int i; /* pointer into prlnbuf */
- int c; /* current character */
- int temp; /* temp used for line number conversion */
-
- start:
- for (i = 0; i < LAST_CH_POS; i++)
- prlnbuf[i] = ' ';
-
- /* if expand_macro get line from macro buffer */
-
- if (expand_macro) {
- if (mlptr == NULL) {
- while (mlptr == NULL) {
- midx--;
- mlptr = mstack[midx];
- mcounter = mcntstack[midx];
- if (midx == 0) {
- mlptr = NULL;
- expand_macro = 0;
- break;
- }
- }
- }
- if (mlptr) {
- i = SFIELD;
- ptr = mlptr->data;
- while (c = *ptr++) {
- if (c != '\\')
- prlnbuf[i++] = c;
- else {
- c = *ptr++;
- prlnbuf[i] = '\0';
- if (c == '@') {
- n = 4;
- sprintf(num, "%04i", mcounter);
- arg = num;
- }
- else if (c >= '1' && c <= '9') {
- j = c - '1';
- n = strlen(marg[midx][j]);
- arg = marg[midx][j];
- }
- else {
- error("Invalid macro argument index!");
- return (-1);
- }
- if ((i + n) >= LAST_CH_POS - 1) {
- error("Invalid line length!");
- return (-1);
- }
- strncpy(&prlnbuf[i], arg, n);
- i += n;
- }
- if (i >= LAST_CH_POS - 1)
- i = LAST_CH_POS - 1;
- }
- prlnbuf[i] = '\0';
- mlptr = mlptr->next;
- return (0);
- }
- }
-
- /* put source line number into prlnbuf. */
-
- i = 4;
- temp = ++slnum;
- while (temp != 0) {
- prlnbuf[i--] = temp % 10 + '0';
- temp /= 10;
- }
- i = SFIELD;
- while ((c = getc(iptr)) != '\n') {
- if(c == '\r')
- continue;
- prlnbuf[i++] = c;
- if (c == '\t') {
- prlnbuf[--i] = ' ';
- i += (8 - ((i - SFIELD) % 8));
- }
- else if (c == EOF) {
- if (close_input())
- return(-1);
- goto start;
- }
- if (i >= LAST_CH_POS - 1)
- i = LAST_CH_POS - 1;
- }
- prlnbuf[i] = '\0';
- return(0);
- }
-
- /*
- * open_input :
- * -----------
- * open an input file, up to 7 levels.
- *
- */
-
- open_input(char *name)
- {
- FILE *fptr;
- char *p;
- int i;
-
- if (infile_num == 7) {
- error("Too many include levels!");
- return (1);
- }
- if (infile_num) {
- input_file[infile_num].lnum = slnum;
- input_file[infile_num].fptr = iptr;
- }
- strcpy(i_file, name);
- /* strupr(i_file);
-
- if (p = strrchr(i_file, '.')) {
- if (strchr(p, '\\'))
- strcat(i_file, ".ASM");
- } else
- strcat(i_file, ".ASM");*/
- if (infile_num) {
- for (i = 1; i < infile_num; i++) {
- if (!strcmp(input_file[i].name, i_file)) {
- error("Repeated include file!");
- return (1);
- }
- }
- }
- if ((fptr = fopen(i_file, "r")) == NULL)
- return (-1);
-
- iptr = fptr;
- slnum = 0;
- infile_num++;
- input_file[infile_num].fptr = fptr;
- strcpy(input_file[infile_num].name, i_file);
- if ((pass == LAST_PASS) && (xlist))
- fprintf(lptr, "#[%i] %s\n", infile_num, input_file[infile_num].name);
- return (0);
- }
-
- /*
- * close_input :
- * ------------
- * close an input file, return -1 if no more files in the stack.
- *
- */
-
- close_input()
- {
- if (infile_num <= 1)
- return (-1);
-
- fclose(iptr);
- infile_num--;
- infile_error = -1;
- slnum = input_file[infile_num].lnum;
- iptr = input_file[infile_num].fptr;
- if ((pass == LAST_PASS) && (xlist))
- fprintf(lptr, "#[%i] %s\n", infile_num, input_file[infile_num].name);
- return (0);
- }
-
-