summaryrefslogtreecommitdiff
path: root/tools/spasm/spasm.c
diff options
context:
space:
mode:
authorXavi Del Campo <xavi.dcr@tutanota.com>2020-01-31 10:32:23 +0100
committerXavi Del Campo <xavi.dcr@tutanota.com>2020-01-31 10:32:23 +0100
commit7c24e9a9b02b04dcaf9507acb94091ea70a2c02d (patch)
treec28d0748652ad4b4222309e46e6cfc82c0906220 /tools/spasm/spasm.c
parenta2b7b6bb1cc2f4a3258b7b2dbc92399d151f864d (diff)
downloadpsxsdk-7c24e9a9b02b04dcaf9507acb94091ea70a2c02d.tar.gz
Imported pristine psxsdk-20190410 from official repo
Diffstat (limited to 'tools/spasm/spasm.c')
-rw-r--r--tools/spasm/spasm.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/tools/spasm/spasm.c b/tools/spasm/spasm.c
new file mode 100644
index 0000000..c94f5a7
--- /dev/null
+++ b/tools/spasm/spasm.c
@@ -0,0 +1,167 @@
+#include "spasm.h"
+#include "fcaseopen.h"
+
+int rawArgc = 0;
+char rawArgv[64][128];
+char *curText;
+char *curLine;
+FILE *asmOut;
+int line_number;
+
+char *fileBuffer;
+unsigned int fileBufferSize;
+
+int open_case_sensitive = 0;
+
+static void titlecard(void)
+{
+ printf("nv-spASM version 0.34.1 (c) 2014-2015 nextvolume\n");
+}
+
+static void usage(char *prog_name)
+{
+ titlecard();
+ printf("Assembler for the Sony PlayStation\n");
+ printf("\n");
+ printf("Usage: %s [options] infile outfile\n", prog_name);
+ printf("\n");
+ printf("Options: -b create binary file instead of PS-X EXE\n");
+ printf(" -N do not pad executable\n");
+ printf(" -S be case sensitive on file paths\n");
+ printf("\n");
+}
+
+FILE *spasm_fopen(const char *path, const char *mode)
+{
+ if(open_case_sensitive)
+ return fopen(path, mode);
+
+ return fcaseopen(path, mode);
+}
+
+int main(int argc, char *argv[])
+{
+ int sz;
+ int farg=1;
+ int bfile=0;
+ int no_newline=0;
+ int no_pad=0;
+
+ if(argc < 3)
+ {
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+
+ while(argv[farg][0] == '-')
+ {
+ if(strcmp(argv[farg], "-b") == 0)
+ bfile = 1; // Generate binary file
+ else if(strcmp(argv[farg], "-N") == 0)
+ no_pad = 1;
+ else if(strcmp(argv[farg], "-S") == 0)
+ open_case_sensitive = 1;
+ else
+ {
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ farg++;
+ }
+
+ FILE *f = spasm_fopen(argv[farg], "rb");
+
+ if(!f)
+ {
+ printf("Could not open file %s for reading! Exiting.\n", argv[farg]);
+ return EXIT_FAILURE;
+ }
+
+ fseek(f, 0, SEEK_END);
+ sz = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ fileBufferSize = sz + 2; // two newline bytes + two NUL bytes
+ fileBuffer = malloc(fileBufferSize);
+ fread(fileBuffer, sizeof(char), sz, f);
+
+ if(fileBuffer[sz-1] != '\n')
+ no_newline = 1;
+
+ fileBuffer[sz] = '\n';
+ fileBuffer[sz+1] = '\0';
+
+ //fileBuffer = process_includes(fileBuffer);
+
+ fclose(f);
+
+ asmOut = fopen(argv[farg+1], "wb");
+
+ if(!asmOut)
+ {
+ printf("Could not open file %s for writing! Exiting.\n", argv[farg+1]);
+ return EXIT_FAILURE;
+ }
+
+ startAddress = 0x80010000;
+
+ titlecard();
+
+ if(no_newline)
+ printf("Warning: No newline found at end of file.\n");
+
+
+ printf("\nPass 1\n");
+ codegen_init();
+ fileBuffer = spasm_parser(fileBuffer, -1);
+ fileBuffer = spasm_parser(fileBuffer, 0);
+
+ /*if(!org_found)
+ {
+ printf("Warning: no ORG directive found... defaulting to $80010000\n");
+ startAddress = 0x80010000;
+ }*/
+
+ curPc = startAddress;
+
+ printf("Pass 2\n");
+ printf("Writing output file %s ...\n", argv[farg+1]);
+
+ if(!bfile)
+ OUTSEEK(0x800);
+
+ fileBuffer = spasm_parser(fileBuffer, 1);
+
+ if(!bfile)
+ {
+ OUTSEEK(0x0);
+ OUTSTRING("\"PS-X EXE\""); // PSX-EXE magic
+ OUTSEEK(0x10);
+ OUTWORD(startAddress); // Initial program counter
+ OUTSEEK(0x18);
+ OUTWORD(startAddress); // Text section start address
+ OUTSEEK(0x30);
+ OUTWORD(0x801FFFF0); // Initial stack pointer
+
+ sz = OUTSIZE();
+
+
+ if(!no_pad && (sz & 2047)) // Pad executable
+ {
+ sz |= 2047;
+ sz++;
+ OUTSEEK(sz-1);
+ OUTBYTE(0);
+ }
+
+ OUTSEEK(0x1C);
+ OUTWORD(sz - 0x800); // Output size of text section
+ }
+
+ printf("\nAssembly complete\n\n");
+
+ fclose(asmOut);
+
+ return EXIT_SUCCESS;
+}