[0.4.1600] - New Assembler Export Functionality

This commit is contained in:
OmniaX 2024-09-02 07:28:56 +02:00
parent a9ba9c8013
commit 8f92a19f28
16 changed files with 797 additions and 688 deletions

View file

@ -98,7 +98,8 @@
"*.ipp": "cpp",
"format": "cpp",
"stdfloat": "cpp",
"*.inc": "cpp"
"*.inc": "cpp",
"text_encoding": "cpp"
},
"workbench.editorAssociations": {
"*.bin": "hexEditor.hexedit"

View file

@ -2,7 +2,7 @@
#-----------------------------------------------------------------------------------------
set(PROJ_NAME DragonVM)
set(MAJOR_VER 0)
set(MINOR_VER 3)
set(MINOR_VER 4)
#-----------------------------------------------------------------------------------------
#Setup
@ -67,6 +67,8 @@ list(APPEND DEBUGGER_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp
${CMAKE_CURRENT_LIST_DIR}/src/assembler/Assembler.cpp
${CMAKE_CURRENT_LIST_DIR}/src/assembler/IncludePreprocessor.cpp
${CMAKE_CURRENT_LIST_DIR}/src/assembler/DASMApp.cpp
${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp
${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp
@ -74,6 +76,8 @@ list(APPEND DEBUGGER_SOURCE_FILES
list(APPEND ASSEMBLER_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/src/assembler/assembler_main.cpp
${CMAKE_CURRENT_LIST_DIR}/src/assembler/Assembler.cpp
${CMAKE_CURRENT_LIST_DIR}/src/assembler/IncludePreprocessor.cpp
${CMAKE_CURRENT_LIST_DIR}/src/assembler/DASMApp.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp

View file

@ -1 +1 @@
1596
1601

Binary file not shown.

View file

@ -2,9 +2,15 @@
@export BIOS_API dss/bios_api.dss
@export_comment BIOS_API " --"
@export_comment BIOS_API " -- This file is automatically generated by the DragonAssembler (version %dasm_version%) "
@export_comment BIOS_API " -- Please do not modify this file in any way. "
@export_comment BIOS_API " --\n"
## ============================= Memory Mapped Devices and Registers =============================
@export_comment /BIOS_API "These are the base addresses of the memory map."
@group /BIOS_API MemoryAddresses
@export_comment BIOS_API "These are the base addresses of the memory map."
@raw_export_start BIOS_API
@group MemoryAddresses
MBR 0x1380
INT_VEC 0x1080
DISK_INTERFACE 0x1580
@ -12,7 +18,8 @@
CMOS 0x1000
VGA 0x1600
@end
@export_comment /BIOS_API "\n"
@raw_export_end
@export_comment BIOS_API " --\n"
@group CMOS_Settings
MEM_START { MemoryAddresses.CMOS + 0x0000 }
@ -25,19 +32,22 @@
@export_comment /BIOS_API "These are the Hardware Interrupt codes of this machine."
@group /BIOS_API HW_Int
@export_comment BIOS_API "These are the Hardware Interrupt codes of this machine."
@raw_export_start BIOS_API
@group HW_Int
DISK_INTERFACE_FINISHED 0x80
KEY_PRESSED 0xA0
KEY_RELEASED 0xA1
TEXT_ENTERED 0xA2
@end
@export_comment /BIOS_API "\n"
@raw_export_end
@export_comment BIOS_API " --\n"
@export_comment /BIOS_API "These are the memory-mapped registers used to interact with the video card's interface."
@group /BIOS_API VGA_Registers
@export_comment BIOS_API "These are the memory-mapped registers used to interact with the video card's interface."
@raw_export_start BIOS_API
@group VGA_Registers
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
SIGNAL { MemoryAddresses.VGA + 0x0003 }
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
@ -46,20 +56,24 @@
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
@end
@export_comment /BIOS_API "\n"
@raw_export_end
@export_comment BIOS_API " --\n"
@export_comment /BIOS_API "These are the different Video Modes that the video card supports."
@group /BIOS_API VGA_VideoModes
@export_comment BIOS_API "These are the different Video Modes that the video card supports."
@raw_export_start BIOS_API
@group VGA_VideoModes
TEXT_SINGLE_COLOR 0x00
@end
@export_comment /BIOS_API "\n"
@raw_export_end
@export_comment BIOS_API " --\n"
@export_comment /BIOS_API "These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode."
@group /BIOS_API Sig_VGA_Text_Single_Color
@export_comment BIOS_API "These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode."
@raw_export_start BIOS_API
@group Sig_VGA_Text_Single_Color
CONTINUE 0x00
PRINT_CHAR 0x02
STORE_CHAR 0x03
@ -71,7 +85,8 @@
REFRESH_SCREEN 0xE0
CLEAR_SCREEN 0xE1
@end
@export_comment /BIOS_API "\n"
@raw_export_end
@export_comment BIOS_API " --\n"
@ -85,8 +100,9 @@
## ========================================== Other Data =========================================
@export_comment /BIOS_API "Structure of a DPT (Dragon Partition Table)."
@group /BIOS_API DPTStructure
@export_comment BIOS_API "Structure of a DPT (Dragon Partition Table)."
@raw_export_start BIOS_API
@group DPTStructure
DISK_ADDR 0x0200
ENTRIES_START 0x000C
@ -98,10 +114,12 @@
ID_CODE 0xF1CA
ENTRY_SIZE_B 100
@end
@export_comment /BIOS_API "\n"
@raw_export_end
@export_comment BIOS_API " --\n"
@export_start /BIOS_API
@export_comment BIOS_API "Structure to store a DPT block."
@raw_export_start BIOS_API
@struct DPTBlock
ID:2
VersionMaj:1
@ -110,7 +128,8 @@
Reserved:7
Entries:500
@end
@export_end
@raw_export_end
@export_comment BIOS_API " --\n"
## ===============================================================================================
.data

View file

@ -1,59 +1,80 @@
## --
## -- This file is automatically generated by the DragonAssembler (version 0.3.1596)
## -- Please do not modify this file in any way.
## --
## --
## -- This file is automatically generated by the DragonAssembler (version 0.3.1599)
## -- Please do not modify this file in any way.
## --
@guard __AUTO_GEN_GUARD_BIOS_API_DSS__
##These are the base addresses of the memory map.
@group MemoryAddresses
MBR 0x1380
INT_VEC 0x1080
DISK_INTERFACE 0x1580
RAM 0x1740
CMOS 0x1000
VGA 0x1600
@end
## --
## -- These are the base addresses of the memory map.
@define MemoryAddresses.MBR 0x1380
@define MemoryAddresses.INT_VEC 0x1080
@define MemoryAddresses.DISK_INTERFACE 0x1580
@define MemoryAddresses.RAM 0x1740
@define MemoryAddresses.CMOS 0x1000
@define MemoryAddresses.VGA 0x1600
## --
##These are the Hardware Interrupt codes of this machine.
@group HW_Int
DISK_INTERFACE_FINISHED 0x80
KEY_PRESSED 0xA0
KEY_RELEASED 0xA1
TEXT_ENTERED 0xA2
@end
## --
## -- These are the Hardware Interrupt codes of this machine.
@define HW_Int.DISK_INTERFACE_FINISHED 0x80
@define HW_Int.KEY_PRESSED 0xA0
@define HW_Int.KEY_RELEASED 0xA1
@define HW_Int.TEXT_ENTERED 0xA2
## --
##These are the memory-mapped registers used to interact with the video card's interface.
@group VGA_Registers
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
SIGNAL { MemoryAddresses.VGA + 0x0003 }
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
TEXT_SIGNLE_INVERT { MemoryAddresses.VGA + 0x0005 }
TEXT_SIGNLE_STR { MemoryAddresses.VGA + 0x0006 }
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
@end
## --
## -- These are the memory-mapped registers used to interact with the video card's interface.
@define VGA_Registers.VIDEO_MODE 0x1600
@define VGA_Registers.SIGNAL 0x1603
@define VGA_Registers.TEXT_SINGLE_CHAR 0x1604
@define VGA_Registers.TEXT_SIGNLE_INVERT 0x1605
@define VGA_Registers.TEXT_SIGNLE_STR 0x1606
@define VGA_Registers.BUFF_START 0x16E0
## --
##These are the different Video Modes that the video card supports.
@group VGA_VideoModes
TEXT_SINGLE_COLOR 0x00
@end
## --
## -- These are the different Video Modes that the video card supports.
@define VGA_VideoModes.TEXT_SINGLE_COLOR 0x00
## --
##These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode.
@group Sig_VGA_Text_Single_Color
CONTINUE 0x00
PRINT_CHAR 0x02
STORE_CHAR 0x03
PRINT_FLUSH_BUFF 0x04
FLUSH_BUFF 0x05
PRINT_BUFF 0x06
PRINT_STRING 0x07
REFRESH_SCREEN 0xE0
CLEAR_SCREEN 0xE1
@end
## --
## -- These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode.
@define Sig_VGA_Text_Single_Color.CONTINUE 0x00
@define Sig_VGA_Text_Single_Color.PRINT_CHAR 0x02
@define Sig_VGA_Text_Single_Color.STORE_CHAR 0x03
@define Sig_VGA_Text_Single_Color.PRINT_FLUSH_BUFF 0x04
@define Sig_VGA_Text_Single_Color.FLUSH_BUFF 0x05
@define Sig_VGA_Text_Single_Color.PRINT_BUFF 0x06
@define Sig_VGA_Text_Single_Color.PRINT_STRING 0x07
@define Sig_VGA_Text_Single_Color.REFRESH_SCREEN 0xE0
@define Sig_VGA_Text_Single_Color.CLEAR_SCREEN 0xE1
## --
##Structure of a DPT (Dragon Partition Table).
@group DPTStructure
DISK_ADDR 0x0200
ENTRIES_START 0x000C
ENTRY_START_ADDR 0x0000
ENTRY_PART_SIZE 0x0004
ENTRY_FLAGS 0x0008
ENTRY_PART_LBL 0x0024
ID_CODE 0xF1CA
ENTRY_SIZE_B 100
@end
## --
## -- Structure of a DPT (Dragon Partition Table).
@define DPTStructure.DISK_ADDR 0x0200
@define DPTStructure.ENTRIES_START 0x000C
@define DPTStructure.ENTRY_START_ADDR 0x0000
@define DPTStructure.ENTRY_PART_SIZE 0x0004
@define DPTStructure.ENTRY_FLAGS 0x0008
@define DPTStructure.ENTRY_PART_LBL 0x0024
@define DPTStructure.ID_CODE 0xF1CA
@define DPTStructure.ENTRY_SIZE_B 100
## --
##Structure to store a DPT block.
@struct DPTBlock
ID:2
VersionMaj:1
VersionMin:1
PartCount:1
Reserved:7
Entries:500
@end
## --

View file

@ -1,19 +1,24 @@
.load 0x1740
@include <dpt.dss>
@include <../bios_api.dss>
.data
$string "Hello BOOTSECTOR!!"
$string "Hello "
$ddd <DiskDriverData>
$dpt_block <DPTBlock>
.code
push 0
call $_load_dpt_block
mov R10, 0x0C
mov R9, $string
int 0x30
push 0
call $_load_dpt_block
mov R10, 0x0C
mov R9, { $dpt_block + DPTStructure.ENTRIES_START + (2 * DPTStructure.ENTRY_SIZE_B) + DPTStructure.ENTRY_PART_LBL }
int 0x30
debug_break
end_loop:
@ -28,14 +33,10 @@ _load_dpt_block:
mov [$ddd.Sector], 0x0000
mov [$ddd.Address], 0x0200
mov [$ddd.DataSize], 512
mov [$ddd.MemoryAddress], $dpt_block.ID
and FL, 0b1111111111111110 ## Disable interrupts
mov FL, ACC
mov [$ddd.MemoryAddress], $dpt_block
push $ddd
push 1
call $_disk_load_from_ddd_blocking
or FL, 0b0000000000000001 ## Enable interrupts
mov FL, ACC
ret

View file

@ -60,7 +60,11 @@ _disk_load_from_ddd_blocking:
addip R1, 2
mov [{DISK_INTERFACE_ADDR + DiskRegisters.MEMORY_ADDRESS}], *R1
movb [{DISK_INTERFACE_ADDR + DiskRegisters.SIGNAL}], DiskSignals.START
and FL, 0b1111111111111110 ## Disable interrupts
mov FL, ACC
_disk_load_from_ddd_blocking_wait_loop:
mov ACC, [{DISK_INTERFACE_ADDR + DiskRegisters.RO_STATUS}]
jne $_disk_load_from_ddd_blocking_wait_loop, DiskStatus.FREE
or FL, 0b0000000000000001 ## Enable interrupts
mov FL, ACC
ret

View file

@ -1,10 +0,0 @@
@guard _DPT_DSS_
@struct DPTBlock
ID:2
VersionMaj:1
VersionMin:1
PartCount:1
Reserved:7
Entries:500
@end

View file

@ -25,13 +25,9 @@
mov [$ddd.DataSize], 5120
mov [$ddd.MemoryAddress], MemoryAddresses.RAM
and FL, 0b1111111111111110 ## Disable interrupts
mov FL, ACC
push $ddd
push 1
call $_disk_load_from_ddd_blocking
or FL, 0b0000000000000001 ## Enable interrupts
mov FL, ACC
jmp MemoryAddresses.RAM

View file

@ -219,4 +219,4 @@
boot-ssector 5 kb 5120 bytes (0x1400) 0x0000.0400 -> 0x0000.17FF
Unallocated 90 kb 92160 bytes (0x16800) 0x0000.1800 -> 0x0001.7FFF
DragonOS 2000 kb 2048000 bytes (0x1F4000) 0x0001.8000 -> 0x0020.BFFF
Test Partition 2000 kb 2048000 bytes (0x1F4000) 0x0020.C000 -> 0x0040.0000
Test Partition 2000 kb 2048000 bytes ( 0x1F4000) 0x0020.C000 -> 0x0040.0000

View file

@ -1,5 +1,4 @@
Assembler:
Add Struct export functionality
Add subroutine address export functionality
Bugs:
@ -14,6 +13,7 @@ External:
Done:
*Add Struct export functionality
*Add evaluation of direct struct instance name as as struct's first member
*Add single Define export functionality
*Inverted Colors in Text-Single-Color

File diff suppressed because it is too large Load diff

View file

@ -69,8 +69,8 @@ namespace dragon
};
public: struct tExportSpec
{
ostd::String fileName;
std::vector<tDefine> content;
ostd::String fileName { "" };
std::vector<ostd::String> lines;
};
public: enum class eOperandType
{
@ -114,20 +114,24 @@ namespace dragon
static ostd::ByteStream assembleToFile(ostd::String sourceFileName, ostd::String binaryFileName);
static ostd::ByteStream assembleToVirtualDisk(ostd::String fileName, hw::VirtualHardDrive& vhdd, uint32_t address);
static bool saveDisassemblyToFile(ostd::String fileName);
static void printProgramInfo(void);
private:
static void removeComments(void);
static void parseExportSpecs(void);
static void processExports(void);
static void replaceDefines(void);
static void replaceGroupDefines(void);
static void parseSections(void);
static void parseStructInstances(void);
static void parseStructures(void);
static void parseStructInstances(void);
static void parseExportSpecifications(void);
static void createExports(void);
static void replaceExportBuiltinVars(void);
static void createExportFiles(void);
static void parseSections(void);
static void parseDataSection(void);
static void parseCodeSection(void);
static void parseDebugOperands(ostd::String line);
static void parse0Operand(ostd::String line);
static void parse1Operand(ostd::String line);
@ -143,22 +147,27 @@ namespace dragon
private:
inline static ostd::String m_rawSource { "" };
inline static ostd::ByteStream m_code;
inline static std::vector<ostd::String> m_lines;
inline static std::vector<ostd::String> m_rawDataSection;
inline static std::vector<ostd::String> m_rawCodeSection;
inline static std::unordered_map<ostd::String, tSymbol> m_symbolTable;
inline static std::unordered_map<ostd::String, tLabel> m_labelTable;
inline static std::unordered_map<ostd::String, tExportSpec> m_exportSpecifications;
inline static uint16_t m_fixedSize { 0 };
inline static uint8_t m_fixedFillValue { 0x00 };
inline static uint16_t m_loadAddress { 0x0000 };
inline static uint16_t m_currentDataAddr { 0x0000 };
inline static uint16_t m_dataSize { 0x0000 };
inline static uint16_t m_programSize { 0x0000 };
inline static std::vector<tStructDefinition> m_structDefs;
inline static std::vector<tDisassemblyLine> m_disassembly;
inline static std::unordered_map<ostd::String, tExportSpec> m_exports;
inline static ostd::ConsoleOutputHandler out;
inline static uint32_t m_exportCommentCount { 0 };
public:
inline static bool saveExports { false };

90
src/assembler/DASMApp.cpp Normal file
View file

@ -0,0 +1,90 @@
#include "Assembler.hpp"
namespace dragon
{
namespace code
{
int32_t Assembler::Application::loadArguments(int argc, char** argv)
{
if (argc < 2)
{
out.fg(ostd::ConsoleColors::Red).p("Error: too few arguments.").nl();
out.fg(ostd::ConsoleColors::Red).p("Use the --help option for more info.").reset().nl();
return RETURN_VAL_TOO_FEW_ARGUMENTS;
}
else
{
args.source_file_path = argv[1];
if (args.source_file_path == "--help")
{
print_application_help();
return RETURN_VAL_CLOSE_PROGRAM;
}
for (int32_t i = 2; i < argc; i++)
{
ostd::String edit(argv[i]);
if (edit == "-o")
{
if (i == argc - 1)
return RETURN_VAL_MISSING_PARAM;
i++;
args.dest_file_path = argv[i];
}
else if (edit == "--save-disassembly")
{
if (i == argc - 1)
return RETURN_VAL_MISSING_PARAM;
i++;
args.disassembly_file_path = argv[i];
args.save_disassembly = true;
}
else if (edit == "--help")
{
print_application_help();
return RETURN_VAL_CLOSE_PROGRAM;
}
else if (edit == "--extmov")
args.cpu_extensions.push_back("extmov");
else if (edit == "--extalu")
args.cpu_extensions.push_back("extalu");
else if (edit == "--verbose")
args.verbose = true;
else if (edit == "--save-exports")
args.save_exports = true;
}
}
return RETURN_VAL_EXIT_SUCCESS;
}
void Assembler::Application::print_application_help(void)
{
int32_t commandLength = 46;
out.nl().fg(ostd::ConsoleColors::Yellow).p("List of available parameters:").reset().nl();
ostd::String tmpCommand = "--save-disassembly <destination-directory>";
tmpCommand.addRightPadding(commandLength);
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Saves debug information in the destination directory.").reset().nl();
tmpCommand = "--verbose";
tmpCommand.addRightPadding(commandLength);
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Shows more information about the assembled program.").reset().nl();
tmpCommand = "-o <destination-binary-file>";
tmpCommand.addRightPadding(commandLength);
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to specify the output binary file.").reset().nl();
tmpCommand = "--save-exports";
tmpCommand.addRightPadding(commandLength);
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to save any specified exports in the code.").reset().nl();
tmpCommand = "--extmov";
tmpCommand.addRightPadding(commandLength);
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Enables mnemonics for the <extmov> CPU extension.").reset().nl();
tmpCommand = "--extalu";
tmpCommand.addRightPadding(commandLength);
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Enables mnemonics for the <extalu> CPU extension.").reset().nl();
tmpCommand = "--help";
tmpCommand.addRightPadding(commandLength);
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Displays this help message.").reset().nl();
out.nl().fg(ostd::ConsoleColors::Magenta).p("Usage: ./dasm <source> -o <destination> [...options...]").reset().nl();
out.nl();
}
}
}

View file

@ -0,0 +1,102 @@
#include "Assembler.hpp"
#include <ostd/File.hpp>
namespace dragon
{
namespace code
{
std::vector<ostd::String> IncludePreprocessor::loadEntryFile(const ostd::String& filePath)
{
m_guards.clear();
m_lines.clear();
m_directory = "";
m_lines = __load_file(filePath);
if (m_lines.size() == 0) return { }; //TODO: Error
if (filePath.contains("/"))
m_directory = filePath.new_substr(0, filePath.lastIndexOf("/") + 1);
if (!__can_file_be_included(m_lines))
return { }; //TODO: Error
if (!__include_loop()) return { }; //TODO: Error
std::vector<ostd::String> newLines;
for (auto& line : m_lines)
{
ostd::String lineEdit = line.new_trim();
if (lineEdit != "")
newLines.push_back(line);
}
m_lines.clear();
m_lines = newLines;
return m_lines;
}
bool IncludePreprocessor::__can_file_be_included(std::vector<ostd::String>& lines)
{
ostd::String guard_name = "";
for (auto& line : lines)
{
ostd::String lineEdit = line.new_trim();
if (lineEdit.new_toLower().startsWith("@guard "))
{
guard_name = lineEdit.new_substr(7).trim();
line = "";
break;
}
}
if (guard_name == "") return true;
for (auto& guard : m_guards)
{
if (guard == guard_name)
return false;
}
m_guards.push_back(guard_name);
return true;
}
bool IncludePreprocessor::__include_loop(void)
{
std::vector<ostd::String> lines = m_lines;
bool included = false;
do
{
included = false;
uint32_t i = 0;
for ( ; i < lines.size(); i++)
{
ostd::String line = lines[i];
line.trim();
if (line.new_toLower().startsWith("@include") && line.len() > 8)
{
line.substr(8).trim();
if (!line.startsWith("<") || !line.endsWith(">"))
return false;
line.substr(1, line.len() - 1).trim();
auto file_lines = __load_file(m_directory + line);
if (file_lines.size() == 0)
return false;
lines.erase(lines.begin() + i);
if (__can_file_be_included(file_lines))
{
lines.insert(lines.begin() + i, file_lines.begin(), file_lines.end());
included = true;
}
break;
}
}
} while(included);
m_lines = lines;
return true;
}
std::vector<ostd::String> IncludePreprocessor::__load_file(const ostd::String& filePath)
{
ostd::TextFileBuffer file(filePath);
if (!file.exists())
return { }; //TODO: Error
ostd::String source = file.rawContent();
return ostd::String(source.replaceAll("\t", " ")).tokenize("\n", false).getRawData();
}
}
}