From 43444d93af0dedec3f6407d9cae2f875c50ef0c9 Mon Sep 17 00:00:00 2001 From: Emmanuel <2860612-e.rousseau@users.noreply.gitlab.com> Date: Fri, 6 Dec 2024 23:41:20 -0500 Subject: [PATCH 1/4] introduces z80 asm generator - allows for more freedom about how the translation is made --- .gitignore | 11 ++++++++ src/Eagle.cpp | 8 ++++++ src/Eagle.hpp | 10 +++---- src/Eagle_asm.cpp | 13 ++++----- src/Eagle_asm_z80.cpp | 57 ++++++++++++++++++++++++---------------- src/Eagle_asm_z80.hpp | 47 +++++++++++++++++++++++++++++++++ src/constant_folding.cpp | 1 + 7 files changed, 113 insertions(+), 34 deletions(-) create mode 100644 .gitignore create mode 100644 src/Eagle_asm_z80.hpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93de617 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# GCC/G++ related + +obj/ +bin/ + +*.o +*.a +*.lib + +# Editors/IDE related +.vscode/ diff --git a/src/Eagle.cpp b/src/Eagle.cpp index 7e66a57..c2f8613 100644 --- a/src/Eagle.cpp +++ b/src/Eagle.cpp @@ -7,6 +7,7 @@ #include +#include "Eagle_asm_z80.hpp" #include "Eagle.hpp" Eagle::Eagle() @@ -77,6 +78,8 @@ Eagle::Eagle() this->keywords[".data.f"] = EAGLE_keywords::DATAF; this->keywords[".data.d"] = EAGLE_keywords::DATAD; + this->asm_z80 = new EagleAsmZ80(*this, this->ilabel); + this->asm_z80->initialize(); this->filetext.reserve(0x200000); this->text_code.reserve(0x200000); @@ -136,6 +139,11 @@ Eagle::Eagle() this->snes_checksum = false; } +Eagle::~Eagle() { + delete this->asm_z80; + this->asm_z80 = nullptr; +} + uint64_t Eagle::alloc(EAGLE_keywords type,int n) { int value; diff --git a/src/Eagle.hpp b/src/Eagle.hpp index 90bd5de..c16088f 100644 --- a/src/Eagle.hpp +++ b/src/Eagle.hpp @@ -16,7 +16,7 @@ typedef struct //Variable -typedef struct +typedef struct EagleVariable { int64_t immediate; // valeur immediate (si bimm == true) double dimmediate; // pareil mais en type double @@ -99,10 +99,13 @@ typedef struct }EAGLE_MNEMONIQUE; +class EagleAsmZ80; + class Eagle { public: Eagle(void); + ~Eagle(void); void parser_word(void); void load_file(const char *path); void write_file(const char *path,std::string text); @@ -172,11 +175,8 @@ class Eagle void asm_call_jump_80186(const EAGLE_VARIABLE &var,int narg,int type); //---------z80-------------- - void asm_return_z80(const EAGLE_VARIABLE &ret,bool retvoid); - void asm_alu_z80(const EAGLE_VARIABLE &dst,const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const char operator1,const char operator2); - void asm_bru_z80(const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const char operator1,const char operator2,int type,int clabel); - void asm_call_jump_z80(const EAGLE_VARIABLE &var,int narg,int type); + EagleAsmZ80 *asm_z80; //---------AltairX-------------- void asm_return_AltairX(const EAGLE_VARIABLE &ret,bool retvoid); diff --git a/src/Eagle_asm.cpp b/src/Eagle_asm.cpp index 52a4c70..864b7f6 100644 --- a/src/Eagle_asm.cpp +++ b/src/Eagle_asm.cpp @@ -10,6 +10,7 @@ #include #include "Eagle.hpp" +#include "Eagle_asm_z80.hpp" void Eagle::asm_bru(const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const char operator1,const char operator2,int type,int clabel) { @@ -20,7 +21,7 @@ void Eagle::asm_bru(const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const asm_bru_6502(src1,src2,operator1,operator2,type,clabel); if(this->target == TARGET_Z80) - asm_bru_z80(src1,src2,operator1,operator2,type,clabel); + this->asm_z80->asm_bru(src1,src2,operator1,operator2,type,clabel); if(this->target == TARGET_AltairX) asm_bru_AltairX(src1,src2,operator1,operator2,type,clabel); @@ -34,8 +35,9 @@ void Eagle::asm_call_jump(const EAGLE_VARIABLE &src,int ninst,int type) if( (this->target == TARGET_6502) | (this->target == TARGET_65C02) | (this->target == TARGET_HuC6520) ) asm_call_jump_6502(src,ninst,type); - if(this->target == TARGET_Z80) - asm_call_jump_z80(src,ninst,type); + if(this->target == TARGET_Z80) { + this->asm_z80->asm_call_jump(src, ninst, type, this->labelcall); + } if(this->target == TARGET_AltairX) asm_call_jump_AltairX(src,ninst,type); @@ -50,8 +52,7 @@ void Eagle::asm_return(const EAGLE_VARIABLE &ret,bool retvoid) asm_return_6502(ret,retvoid); if(this->target == TARGET_Z80) - asm_return_z80(ret,retvoid); - + this->asm_z80->asm_return(ret,retvoid); if(this->target == TARGET_AltairX) asm_return_AltairX(ret,retvoid); @@ -66,7 +67,7 @@ void Eagle::asm_alu(const EAGLE_VARIABLE &dst,const EAGLE_VARIABLE &src1,const E asm_alu_6502(dst,src1,src2,operator1,operator2); if(this->target == TARGET_Z80) - asm_alu_z80(dst,src1,src2,operator1,operator2); + this->asm_z80->asm_alu(dst,src1,src2,operator1,operator2); if(this->target == TARGET_AltairX) asm_alu_AltairX(dst,src1,src2,operator1,operator2); diff --git a/src/Eagle_asm_z80.cpp b/src/Eagle_asm_z80.cpp index f455e34..a8c1e61 100644 --- a/src/Eagle_asm_z80.cpp +++ b/src/Eagle_asm_z80.cpp @@ -7,13 +7,21 @@ #include +#include "Eagle_asm_z80.hpp" #include "Eagle.hpp" #define TYPE_LOOP 0 #define TYPE_WHILE 1 #define TYPE_IF 2 -void Eagle::asm_bru_z80(const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const char operator1,const char operator2,int type,int clabel) +EagleAsmZ80::EagleAsmZ80(Eagle &eagle, int &ilabel) : eagle(eagle), ilabel(ilabel) {} + +void EagleAsmZ80::initialize() { + // more to come here + this->ilabel = 0U; +} + +void EagleAsmZ80::asm_bru(const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const char operator1,const char operator2,int type,int clabel) { std::string label_adr = ".label_b"+std::to_string(clabel); @@ -25,19 +33,22 @@ void Eagle::asm_bru_z80(const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,co if(src1.type == EAGLE_keywords::IDX) { - this->text_code += "dex \n"; + this->eagle.text_code += "dex \n"; }else if(src1.type == EAGLE_keywords::IDY) { - this->text_code += "dey \n"; + this->eagle.text_code += "dey \n"; } - this->text_code += "cp \n"; + this->eagle.text_code += "cp \n"; - this->text_code += "jp " + label_adr + "\n"; + this->eagle.text_code += "jp " + label_adr + "\n"; } -void Eagle::asm_call_jump_z80(const EAGLE_VARIABLE &src,int ninst,int type) +void EagleAsmZ80::asm_call_jump(const EAGLE_VARIABLE &src, + int ninst, + int type, + std::string &labelcall) { std::string mnemonic = "jp ",mne1,mne2,saddress,saddress2; if(type >= 1) @@ -50,7 +61,7 @@ void Eagle::asm_call_jump_z80(const EAGLE_VARIABLE &src,int ninst,int type) } //------ - std::string src1value = this->labelcall; + std::string src1value = labelcall; if(src.bimm == true) { src1value = std::to_string(src.immediate); @@ -61,7 +72,7 @@ void Eagle::asm_call_jump_z80(const EAGLE_VARIABLE &src,int ninst,int type) if(src.type == EAGLE_keywords::UINT16) { - this->text_code += "ld hl," + std::to_string(src.address) +"\n"; + this->eagle.text_code += "ld hl," + std::to_string(src.address) +"\n"; src1value = "(hl)"; } @@ -77,40 +88,40 @@ void Eagle::asm_call_jump_z80(const EAGLE_VARIABLE &src,int ninst,int type) } } - this->text_code += mnemonic + src1value +"\n"; + this->eagle.text_code += mnemonic + src1value +"\n"; } -void Eagle::asm_return_z80(const EAGLE_VARIABLE &ret,bool retvoid) +void EagleAsmZ80::asm_return(const EAGLE_VARIABLE &ret,bool retvoid) { if(retvoid == true) { - this->text_code += "ret\n"; + this->eagle.text_code += "ret\n"; }else { if(ret.type == EAGLE_keywords::IDX) { - this->text_code += "ld a,IX\n"; + this->eagle.text_code += "ld a,IX\n"; } if(ret.type == EAGLE_keywords::IDY) { - this->text_code += "ld a,IY\n"; + this->eagle.text_code += "ld a,IY\n"; } if(ret.type != EAGLE_keywords::ACC) { if(ret.bimm == true) - this->text_code += "ld a,"+ std::to_string(ret.immediate&0xFF) +"\n"; + this->eagle.text_code += "ld a,"+ std::to_string(ret.immediate&0xFF) +"\n"; else - this->text_code += "lda a,("+ std::to_string(ret.address) +")\n"; + this->eagle.text_code += "lda a,("+ std::to_string(ret.address) +")\n"; } - this->text_code += "ret\n"; + this->eagle.text_code += "ret\n"; } } -void Eagle::asm_alu_z80(const EAGLE_VARIABLE &dst,const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const char operator1,const char operator2) +void EagleAsmZ80::asm_alu(const EAGLE_VARIABLE &dst,const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const char operator1,const char operator2) { std::string mnemonic; std::string src1value,dstvalue; @@ -146,8 +157,8 @@ void Eagle::asm_alu_z80(const EAGLE_VARIABLE &dst,const EAGLE_VARIABLE &src1,con if(operator1 == '=') { - this->text_code += "ld a," + src2value + "\n"; - this->text_code += "ld " + dstvalue + ",a\n"; + this->eagle.text_code += "ld a," + src2value + "\n"; + this->eagle.text_code += "ld " + dstvalue + ",a\n"; return; } @@ -184,10 +195,10 @@ void Eagle::asm_alu_z80(const EAGLE_VARIABLE &dst,const EAGLE_VARIABLE &src1,con } - this->text_code += "ld a," + src1value + "\n"; - this->text_code += "ld b," + src2value + "\n"; + this->eagle.text_code += "ld a," + src1value + "\n"; + this->eagle.text_code += "ld b," + src2value + "\n"; - this->text_code += mnemonic + reg +"\n"; + this->eagle.text_code += mnemonic + reg +"\n"; - this->text_code += "ld " + dstvalue + ",a\n"; + this->eagle.text_code += "ld " + dstvalue + ",a\n"; } diff --git a/src/Eagle_asm_z80.hpp b/src/Eagle_asm_z80.hpp new file mode 100644 index 0000000..4aaba73 --- /dev/null +++ b/src/Eagle_asm_z80.hpp @@ -0,0 +1,47 @@ +#pragma once + +// Forward declarations -------------------------------------------------------- + +typedef struct EagleVariable EAGLE_VARIABLE; +class Eagle; + + +// Types ----------------------------------------------------------------------- + +// EagleZ80 - assembly code generation for Z80 +class EagleAsmZ80 { + public: + EagleAsmZ80(Eagle &eagle, int &ilabel); + + // initialize the Z80 translation engine. Resets all the internal states. + void initialize(void); + + // asm_return_z80 translates a return operation + void asm_return(const EAGLE_VARIABLE &ret, bool retvoid); + + // asm_alu_z80 translates an ALU operation + void asm_alu(const EAGLE_VARIABLE &dst, + const EAGLE_VARIABLE &src1, + const EAGLE_VARIABLE &src2, + const char operator1, + const char operator2); + + // asm_bru_z80 translates a local control structures, IF, WHILE, DO etc. + void asm_bru(const EAGLE_VARIABLE &src1, + const EAGLE_VARIABLE &src2, + const char operator1, + const char operator2, + int type, + int clabel); + + // asm_call_jump_z80 translates a CALL or JMP operation + void asm_call_jump(const EAGLE_VARIABLE &var, + int narg, + int type, + std::string &labelcall); + + private: + Eagle &eagle; + // temporary hack, needs to be discussed + int &ilabel; +}; diff --git a/src/constant_folding.cpp b/src/constant_folding.cpp index c34f5cf..1843e8d 100644 --- a/src/constant_folding.cpp +++ b/src/constant_folding.cpp @@ -253,6 +253,7 @@ void Constant_folding::apply_operation() //----------------------- +__attribute__((unused)) static std::string formatExpression(const std::string& expression) { std::string result; From fe7118f65b0364ea576014b979e4c561e0d7090d Mon Sep 17 00:00:00 2001 From: Emmanuel <2860612-e.rousseau@users.noreply.gitlab.com> Date: Sat, 7 Dec 2024 00:07:32 -0500 Subject: [PATCH 2/4] ixes mixed indent !? and error in initializer --- src/Eagle_asm_z80.cpp | 1 - src/Eagle_asm_z80.hpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Eagle_asm_z80.cpp b/src/Eagle_asm_z80.cpp index a8c1e61..d52f6cb 100644 --- a/src/Eagle_asm_z80.cpp +++ b/src/Eagle_asm_z80.cpp @@ -18,7 +18,6 @@ EagleAsmZ80::EagleAsmZ80(Eagle &eagle, int &ilabel) : eagle(eagle), ilabel(ilabe void EagleAsmZ80::initialize() { // more to come here - this->ilabel = 0U; } void EagleAsmZ80::asm_bru(const EAGLE_VARIABLE &src1,const EAGLE_VARIABLE &src2,const char operator1,const char operator2,int type,int clabel) diff --git a/src/Eagle_asm_z80.hpp b/src/Eagle_asm_z80.hpp index 4aaba73..c9c05cb 100644 --- a/src/Eagle_asm_z80.hpp +++ b/src/Eagle_asm_z80.hpp @@ -41,7 +41,7 @@ class EagleAsmZ80 { std::string &labelcall); private: - Eagle &eagle; + Eagle &eagle; // temporary hack, needs to be discussed int &ilabel; }; From 78418a17f94a179491818d4b6e946451d597b4ff Mon Sep 17 00:00:00 2001 From: Emmanuel <2860612-e.rousseau@users.noreply.gitlab.com> Date: Sat, 7 Dec 2024 00:21:01 -0500 Subject: [PATCH 3/4] fixes more mixed indent, vscode is bad at guessing it seems --- src/Eagle.cpp | 1 + src/Eagle_asm.cpp | 4 +-- src/Eagle_asm_z80.hpp | 68 +++++++++++++++++++++---------------------- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/Eagle.cpp b/src/Eagle.cpp index c2f8613..52e7d63 100644 --- a/src/Eagle.cpp +++ b/src/Eagle.cpp @@ -79,6 +79,7 @@ Eagle::Eagle() this->keywords[".data.d"] = EAGLE_keywords::DATAD; this->asm_z80 = new EagleAsmZ80(*this, this->ilabel); + this->asm_z80->initialize(); this->filetext.reserve(0x200000); diff --git a/src/Eagle_asm.cpp b/src/Eagle_asm.cpp index 864b7f6..f3fc988 100644 --- a/src/Eagle_asm.cpp +++ b/src/Eagle_asm.cpp @@ -52,7 +52,7 @@ void Eagle::asm_return(const EAGLE_VARIABLE &ret,bool retvoid) asm_return_6502(ret,retvoid); if(this->target == TARGET_Z80) - this->asm_z80->asm_return(ret,retvoid); + this->asm_z80->asm_return(ret,retvoid); if(this->target == TARGET_AltairX) asm_return_AltairX(ret,retvoid); @@ -67,7 +67,7 @@ void Eagle::asm_alu(const EAGLE_VARIABLE &dst,const EAGLE_VARIABLE &src1,const E asm_alu_6502(dst,src1,src2,operator1,operator2); if(this->target == TARGET_Z80) - this->asm_z80->asm_alu(dst,src1,src2,operator1,operator2); + this->asm_z80->asm_alu(dst,src1,src2,operator1,operator2); if(this->target == TARGET_AltairX) asm_alu_AltairX(dst,src1,src2,operator1,operator2); diff --git a/src/Eagle_asm_z80.hpp b/src/Eagle_asm_z80.hpp index c9c05cb..e1bd4be 100644 --- a/src/Eagle_asm_z80.hpp +++ b/src/Eagle_asm_z80.hpp @@ -10,38 +10,38 @@ class Eagle; // EagleZ80 - assembly code generation for Z80 class EagleAsmZ80 { - public: - EagleAsmZ80(Eagle &eagle, int &ilabel); - - // initialize the Z80 translation engine. Resets all the internal states. - void initialize(void); - - // asm_return_z80 translates a return operation - void asm_return(const EAGLE_VARIABLE &ret, bool retvoid); - - // asm_alu_z80 translates an ALU operation - void asm_alu(const EAGLE_VARIABLE &dst, - const EAGLE_VARIABLE &src1, - const EAGLE_VARIABLE &src2, - const char operator1, - const char operator2); - - // asm_bru_z80 translates a local control structures, IF, WHILE, DO etc. - void asm_bru(const EAGLE_VARIABLE &src1, - const EAGLE_VARIABLE &src2, - const char operator1, - const char operator2, - int type, - int clabel); - - // asm_call_jump_z80 translates a CALL or JMP operation - void asm_call_jump(const EAGLE_VARIABLE &var, - int narg, - int type, - std::string &labelcall); - - private: - Eagle &eagle; - // temporary hack, needs to be discussed - int &ilabel; + public: + EagleAsmZ80(Eagle &eagle, int &ilabel); + + // initialize the Z80 translation engine. Resets all the internal states. + void initialize(void); + + // asm_return_z80 translates a return operation + void asm_return(const EAGLE_VARIABLE &ret, bool retvoid); + + // asm_alu_z80 translates an ALU operation + void asm_alu(const EAGLE_VARIABLE &dst, + const EAGLE_VARIABLE &src1, + const EAGLE_VARIABLE &src2, + const char operator1, + const char operator2); + + // asm_bru_z80 translates a local control structures, IF, WHILE, DO etc. + void asm_bru(const EAGLE_VARIABLE &src1, + const EAGLE_VARIABLE &src2, + const char operator1, + const char operator2, + int type, + int clabel); + + // asm_call_jump_z80 translates a CALL or JMP operation + void asm_call_jump(const EAGLE_VARIABLE &var, + int narg, + int type, + std::string &labelcall); + + private: + Eagle &eagle; + // temporary hack, needs to be discussed + int &ilabel; }; From 5081f23f9ccbd1b08e424b8b2a1a22bd0c895759 Mon Sep 17 00:00:00 2001 From: Emmanuel <2860612-e.rousseau@users.noreply.gitlab.com> Date: Sat, 7 Dec 2024 00:23:20 -0500 Subject: [PATCH 4/4] remove irregularities --- src/Eagle.cpp | 1 - src/Eagle_asm.cpp | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Eagle.cpp b/src/Eagle.cpp index 52e7d63..c2f8613 100644 --- a/src/Eagle.cpp +++ b/src/Eagle.cpp @@ -79,7 +79,6 @@ Eagle::Eagle() this->keywords[".data.d"] = EAGLE_keywords::DATAD; this->asm_z80 = new EagleAsmZ80(*this, this->ilabel); - this->asm_z80->initialize(); this->filetext.reserve(0x200000); diff --git a/src/Eagle_asm.cpp b/src/Eagle_asm.cpp index f3fc988..baaea92 100644 --- a/src/Eagle_asm.cpp +++ b/src/Eagle_asm.cpp @@ -35,9 +35,8 @@ void Eagle::asm_call_jump(const EAGLE_VARIABLE &src,int ninst,int type) if( (this->target == TARGET_6502) | (this->target == TARGET_65C02) | (this->target == TARGET_HuC6520) ) asm_call_jump_6502(src,ninst,type); - if(this->target == TARGET_Z80) { + if(this->target == TARGET_Z80) this->asm_z80->asm_call_jump(src, ninst, type, this->labelcall); - } if(this->target == TARGET_AltairX) asm_call_jump_AltairX(src,ninst,type);