From 05793ad4ae677696fa93d17797440599a9bc2511 Mon Sep 17 00:00:00 2001 From: sfja Date: Mon, 31 Mar 2025 23:37:50 +0200 Subject: [PATCH] all far call and ret --- asm/asm.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ asm/asm.h | 10 +++++++++ asm/ctors.c | 36 ++++++++++++++++++++++++++++++++ vm/main.c | 2 +- 4 files changed, 106 insertions(+), 1 deletion(-) diff --git a/asm/asm.c b/asm/asm.c index 4f4cfc1..c12cf6b 100644 --- a/asm/asm.c +++ b/asm/asm.c @@ -1,5 +1,6 @@ #include "asm.h" #include "common/arch.h" +#include "common/fmt_binary.h" #include "common/op_str.h" #include #include @@ -535,11 +536,69 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(op1); break; } + case LineTy_CallFar_Reg_Reg: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Jmp; + ins |= 1 << 13; + add_op1_reg(&ins, op1); + ins |= (op2 << 7) & 0x7; + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_CallFar_Reg_Imm: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Jmp; + ins |= 1 << 13; + ins |= 1 << 14; + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_CallFar_Imm_Reg: { + uint16_t op1 = line->op1.imm; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Jmp; + ins |= 1 << 13; + set_is_imm(&ins); + ins |= (op2 << 7) & 0x7; + + out[ip++] = (uint16_t)ins; + out[ip++] = op1; + break; + } + case LineTy_CallFar_Imm_Imm: { + uint16_t op1 = line->op1.imm; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Jmp; + ins |= 1 << 13; + ins |= 1 << 14; + set_is_imm(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + out[ip++] = op1; + break; + } case LineTy_Ret: { uint32_t ins = Op_Ret; out[ip++] = (uint16_t)ins; break; } + case LineTy_RetFar: { + uint32_t ins = Op_Ret; + ins |= 1 << 6; + out[ip++] = (uint16_t)ins; + break; + } case LineTy_Lit_Reg: { uint16_t op1 = line->op1.reg; diff --git a/asm/asm.h b/asm/asm.h index b00f642..b3990ea 100644 --- a/asm/asm.h +++ b/asm/asm.h @@ -47,7 +47,12 @@ typedef enum { LineTy_Call_Reg, LineTy_Call_Imm, LineTy_Call_Label, + LineTy_CallFar_Reg_Reg, + LineTy_CallFar_Reg_Imm, + LineTy_CallFar_Imm_Reg, + LineTy_CallFar_Imm_Imm, LineTy_Ret, + LineTy_RetFar, LineTy_Lit_Reg, LineTy_Lit_Imm, LineTy_Lit_Label, @@ -154,7 +159,12 @@ Line s_in_i(Reg dst_reg, uint16_t op1_imm); Line s_call_r(Reg op1_reg); Line s_call_i(uint16_t op1_imm); Line s_call_l(int op1_label); +Line s_callf_r_r(Reg op1_reg, Reg op2_reg); +Line s_callf_r_i(Reg op1_reg, uint16_t op2_imm); +Line s_callf_i_r(uint16_t op1_imm, Reg op2_reg); +Line s_callf_i_i(uint16_t op1_imm, uint16_t op2_imm); Line s_ret(void); +Line s_retf(void); Line s_lit_r(Reg op1_reg); Line s_lit_i(uint16_t op1_imm); Line s_lit_l(int op1_label); diff --git a/asm/ctors.c b/asm/ctors.c index 939ad1e..6d88504 100644 --- a/asm/ctors.c +++ b/asm/ctors.c @@ -325,10 +325,46 @@ Line s_call_l(int op1_label) .op1 = (Ex) { .label = op1_label }, }; } +Line s_callf_r_r(Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_CallFar_Reg_Reg, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_callf_r_i(Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_CallFar_Reg_Imm, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_callf_i_r(uint16_t op1_imm, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_CallFar_Imm_Reg, + .op1 = (Ex) { .imm = op1_imm }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_callf_i_i(uint16_t op1_imm, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_CallFar_Imm_Imm, + .op1 = (Ex) { .imm = op1_imm }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} Line s_ret(void) { return (Line) { .ty = LineTy_Ret }; } +Line s_retf(void) +{ + return (Line) { .ty = LineTy_RetFar }; +} Line s_lit_r(Reg op1_reg) { return (Line) { diff --git a/vm/main.c b/vm/main.c index 466b531..db0c9f7 100644 --- a/vm/main.c +++ b/vm/main.c @@ -1,4 +1,4 @@ -#include "asm/asm.h" +#include "common/fmt_binary.h" #include "common/op_str.h" #include "common/video_character_display.h" #include "vm.h"