X-Git-Url: https://jxself.org/git/?p=zilutils.git;a=blobdiff_plain;f=zilasm%2Fcompiler.cpp;fp=zilasm%2Fcompiler.cpp;h=eaa2317e17f188887031cef366bea4e071d2f28f;hp=0000000000000000000000000000000000000000;hb=b1f151e1500e1fdadafaab6b13df6e0a8f32136e;hpb=c0f515aab1285fdedb65d4582b42cc59db0c8e26 diff --git a/zilasm/compiler.cpp b/zilasm/compiler.cpp new file mode 100644 index 0000000..eaa2317 --- /dev/null +++ b/zilasm/compiler.cpp @@ -0,0 +1,138 @@ +/* +* parser.c -- part of ZilUtils/ZilAsm +* +* Copyright (C) 2020 Jason Self +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see +* +* SPDX-License-Identifier: AGPL-3.0-or-later +*/ + +#include "include_all.h" + +CCompiler::CCompiler() :m_output_file(NULL) +{ +} + +int +CCompiler::assembly() +{ + FILE *file = fopen(m_output_file, "wb"); + if (file) + { + program_header_reset(6); + int size = sizeof(program_header); + + program_header.mode = 0; + program_header.release = 1; // game version + + m_code_size = 0; + ZMemblock *zmem_code = zmem_init(65536); + + unsigned current_address = 64; + + if (parser.m_functions.size() > 0) + { + //unsigned function_table_size = parser.m_functions.size() * 2; + program_header.H_FUNCTIONS_OFFSET = current_address >> 3; + //current_address += function_table_size; + } + else + program_header.H_FUNCTIONS_OFFSET = 0; + + int code_start_offset = current_address; + + if (parser.m_start_function_name == "") + program_header.startPC = code_start_offset >> 2; + else + program_header.startPC = parser.m_functions.find(parser.m_start_function_name)->second.address >> 2; + + // write instructions' codes + m_code_size = parser.output_codes(zmem_code); + + if (m_code_size & 7) + { + const int additional_mem = 8 - (m_code_size & 7); + for (int i = 0; i < additional_mem; ++i) + zmem_putbyte(zmem_code, 0); + m_code_size += additional_mem; + } + + program_header.dynamic_size = 8; + + //Program_header.h_file_size = 33; //sizeof(Program_header) + zmb->used_size; + + //m_code_size = 8; + + Word stringTableOffset = m_code_size; + program_header.H_STRINGS_OFFSET = (64 + stringTableOffset) >> 3; + + int stringTableSize = 64; + program_header.h_file_size = + (code_start_offset + m_code_size + stringTableSize) >> 3; + ZMemblock *zmb = zmem_init(program_header.h_file_size * 8); + + for (int i = 0; i < m_code_size; ++i) + zmem_putbyte(zmb, zmem_code->contents[i]); + + zmem_destroy(zmem_code); + + //zmem_putbyte(zmb, 0); // number of local variables + //zmem_putbyte(zmb, 141); // print addr command + + //Word offset = 0; + //zmem_putbyte(zmb, (offset >> 8) & 255); + //zmem_putbyte(zmb, offset & 255); + + //zmem_putbyte(zmb, 186); // quit command + + // output zeros until string table begins + while (zmb->used_size < stringTableOffset) + zmem_putbyte(zmb, 0); + // + //// fill string table with one string + //add_string_to_string_table("Hello, World!", zmb); + + outputToFile(&program_header, file); + //output_function_table(file); + + fwrite(zmb->contents, zmb->allocated_size, 1, file); + fclose(file); + } + + return OK; +} + + +char * +CCompiler::get_output_file_name() +{ + return m_output_file; +} + + +void +CCompiler::output_function_table(FILE *file) +{ + if (parser.m_functions.size()) + { + for(map::iterator iter = parser.m_functions.begin(); iter != parser.m_functions.end(); ++iter) + { + Word w = (iter->second.address) >> 4; + fprintf ( file, "%c", (w >> 8) & 255); + fprintf(file, "%c", w & 255); + } + + } +} \ No newline at end of file