Implemented ExtAlu CPU extension + Bios logo

This commit is contained in:
OmniaX-dev 2024-04-02 00:56:59 +02:00
parent f40ae0a036
commit f256b901a1
32 changed files with 807 additions and 103 deletions

View file

@ -9,7 +9,7 @@
"defines": [],
"compilerPath": "/usr/bin/clang++",
"cStandard": "c17",
"cppStandard": "c++20",
"cppStandard": "c++23",
"intelliSenseMode": "linux-clang-x64"
//"compileCommands": "${workspaceFolder}/compile_commands.json"
},
@ -22,7 +22,7 @@
"defines": [],
"compilerPath": "C:\\msys64\\ucrt64\\bin\\clang++",
"cStandard": "c17",
"cppStandard": "c++20",
"cppStandard": "c++23",
"intelliSenseMode": "windows-clang-x64"
//"compileCommands": "${workspaceFolder}/compile_commands.json"
}

View file

@ -13,7 +13,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
cmake_minimum_required(VERSION 3.18)
project(${PROJ_NAME} LANGUAGES C CXX)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
file(STRINGS "./build.nr" BUILD_NUMBER)
#-----------------------------------------------------------------------------------------

View file

@ -1 +1 @@
1589
1590

View file

@ -1,7 +1,9 @@
Disks = dragon/disk1.dr
Bios = dragon/bios.bin
CMOS = dragon/cmos.dr
cpuext = extmov
cpuext = extmov, extalu
fixed_clock = false
clock_rate_sec = 512
SingleColor_foreground = #009900FF
SingleColor_background = #111111FF

View file

@ -7,7 +7,13 @@
0x0FFF
-------
0x1000 CMOS (128 Bytes) (write to this section is only allowed in BIOS Mode)
MemStart: (2 bytes) 0x0000
MemSize: (2 bytes) 0x0002
ClockSpeed: (2 bytes) 0x0004
BootDisk: 0x0010
ICC_
ICC_OutputAddr: (2 bytes) 0x007E
0x107F
-------
0x1080 INTERRUPT VECTOR (512 Bytes)
@ -90,7 +96,8 @@
0xE0: Refresh Screen
0xE1: Clear Screen
0x04: Text Single Color Character
0x04: Text Single Color Character (1 Byte)
0x05: Text Single Color Inverted colors (1 Byte)
0x16FF
-------
0x1700 GENERIC SERIAL INTERFACE (64 Bytes)
@ -125,6 +132,7 @@ BIOS Specific - Software Interrupts:
0x08: Print buffer and flush in Text Single Mode
0x09: Flush buffer in Text Single Mode
0x0A: Store Null-Terminated String in buffer in Text Single Mode (string address stored in R9 register)
0x0B: Toggles inverted colors in Text Single Mode
0xE0: Refresh Screen
0xE1: Clear Screen

View file

@ -1,9 +1,8 @@
Text visualization for hardware interrupts (in call-tree view)
Inverted Colors in Text-Single-Color
show where interrupts are disabled (in call-tree view)
#***Inverted Colors in Text-Single-Color
#***show where interrupts are disabled (in call-tree view)
#***Text visualization for hardware interrupts (in call-tree view)
#***Add possibility to specify instruction sets in machine config
Add possibility to specify required instruction sets in dasm
#***Add possibility to specify required instruction sets in dasm
#***Add "Extended mov" instruction set
#***Remove old offset mov
#***Implelemnt extmov mnemonics in dasm:

Binary file not shown.

Binary file not shown.

View file

@ -13,6 +13,9 @@
@end
@group CMOS_Settings
MEM_START { MemoryAddresses.CMOS + 0x0000 }
MEM_SIZE { MemoryAddresses.CMOS + 0x0002 }
CLOCK_SPEED { MemoryAddresses.CMOS + 0x0004 }
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
@end
@ -34,6 +37,7 @@
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
SIGNAL { MemoryAddresses.VGA + 0x0003 }
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
TEXT_SIGNLE_INVERT { MemoryAddresses.VGA + 0x0005 }
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
@end
@ -73,6 +77,39 @@
## ===============================================================================================
.data
$_bios_name "DragonBIOS"
$_bios_version_number_maj 0x00, 0x00
$_bios_version_number_min 0x00, 0x03
$_bios_version_number_min 0x00, 0x03
$_bios_name " DragonBIOS "
$_clock_str " Clock: "
$_mem_str " Memory: "
$_hz_str " Hz"
$_byte_str " Bytes"
$_bios_logo_2_line_1 "|===================================================|"
$_bios_logo_2_line_2 "| '$$$o. |"
$_bios_logo_2_line_3 "| '$$$$bo... ..o: |"
$_bios_logo_2_line_4 "| '$$$$$$$$booocS$$$ .. ,. |"
$_bios_logo_2_line_5 "| '. '*$$$$SP V$o..o$$. .$$$b |"
$_bios_logo_2_line_6 "| '$$o. .$$$$$o. ...A$$$$$$$$$$$$$$b |"
$_bios_logo_2_line_7 "| ''bo. '*$$$$$$$$$$$$$$$$$$$$P*$$$$$$$$: |"
$_bios_logo_2_line_8 "| '$$. V$$$$$$$$$P'**''*'' VP * 'l |"
$_bios_logo_2_line_9 "| '$$$o.4$$$$$$$$X |"
$_bios_logo_2_line_10 "| '*$$$$$$$$$$$$$AoA$o..oooooo.. .b |"
$_bios_logo_2_line_11 "| .X$$$$$$$$$$$P'' ''*oo,, ,$P |"
$_bios_logo_2_line_12 "| $$P''V$$$$$$$: . ''*****' |"
$_bios_logo_2_line_13 "| .*' A$$$$$$$$o.4; . |"
$_bios_logo_2_line_14 "| .oP'' '$$$$$$b. .$; |"
$_bios_logo_2_line_15 "| A$$$$$$$$$$P |"
$_bios_logo_2_line_16 "| ' '$$$$$P' |"
$_bios_logo_2_line_17 "| $$P*' |"
$_bios_logo_2_line_18 "| .$' |"
$_bios_logo_2_line_19 "|===================================================|"
## $_bios_logo_line_1 " _____ ____ _____ ____ _____ "
## $_bios_logo_line_2 " | __ \ | _ \_ _/ __ \ / ____| "
## $_bios_logo_line_3 " | | | |_ __ __ _ __ _ ___ _ __ | |_) || || | | | (___ "
## $_bios_logo_line_4 " | | | | '__/ _` |/ _` |/ _ \| '_ \| _ < | || | | |\___ \ "
## $_bios_logo_line_5 " | |__| | | | (_| | (_| | (_) | | | | |_) || || |__| |____) | "
## $_bios_logo_line_6 " |_____/|_| \__,_|\__, |\___/|_| |_|____/_____\____/|_____/ "
## $_bios_logo_line_7 " __/ | "
## $_bios_logo_line_8 " |___/ "

View file

@ -52,6 +52,7 @@ _int_30_handler:
jeq $_int_30_print_buffer_and_flush_text_single, 0x0008
jeq $_int_30_flush_buffer_text_single, 0x0009
jeq $_int_30_store_string_text_single, 0x000A
jeq $_int_30_invert_colors_text_single, 0x000B
jeq $_int_30_clear_screen, 0x00E0
jeq $_int_30_refresh_screen, 0x00E1
jmp $_int_30_end
@ -105,6 +106,14 @@ _int_30_store_string_text_single:
movb ACC, *R9
jne $_int_30_store_string_text_single, 0
jmp $_int_30_end
_int_30_invert_colors_text_single:
movb ACC, [VGA_Registers.TEXT_SIGNLE_INVERT]
jne $_int_30_invert_colors_text_single_normal, 0
movb [VGA_Registers.TEXT_SIGNLE_INVERT], 1
jmp $_int_30_end
_int_30_invert_colors_text_single_normal:
movb [VGA_Registers.TEXT_SIGNLE_INVERT], 0
jmp $_int_30_end
_int_30_clear_screen:

View file

@ -14,23 +14,8 @@
mov R8, 0x30 ## -Passing the interrupt's code to setup
int 0x20 ## -Calling int 0x20 with 0x00 as parameter, to set new handler up
mov R10, 0x03
mov R9, $_bios_name
int 0x30
mov R10, 0x01
mov R9, 32
int 0x30
mov R10, 0x04
mov R9, [$_bios_version_number_maj]
int 0x30
mov R10, 0x01
mov R9, 46
int 0x30
mov R10, 0x04
mov R9, [$_bios_version_number_min]
int 0x30
mov R10, 0x02
int 0x30
push 0
call $_print_machine_info
## MBR Loading
and FL, 0b1111111111111110 ## Disable interrupts
@ -49,4 +34,134 @@
@include <drivers.dss>
@include <utils.dss>
_print_machine_info:
mov R9, $_bios_logo_2_line_1
mov R10, 0x0A
int 0x30
mov R10, 0x08 ## Print and flush buffer
int 0x30
mov R10, 0x02
int 0x30
mov R9, $_bios_logo_2_line_2
mov R10, 0x0A
int 0x30
mov R10, 0x08 ## Print and flush buffer
int 0x30
mov R10, 0x0A
mov R9, $_bios_name
int 0x30 ## Print BIOS Name
mov R10, 0x05
mov R9, [$_bios_version_number_maj]
int 0x30 ## Print BIOS Version (Major)
mov R10, 0x06
mov R9, 46
int 0x30 ## Print '.' character
mov R10, 0x05
mov R9, [$_bios_version_number_min]
int 0x30 ## Print BIOS Version (Minor)
mov R10, 0x02
int 0x30 ## Print New Line
mov R9, $_bios_logo_2_line_3
mov R10, 0x0A
int 0x30
mov R10, 0x08 ## Print and flush buffer
int 0x30
mov R10, 0x0A
mov R9, $_clock_str
int 0x30 ## Print Clock label
mov R10, 0x05
mov R9, [CMOS_Settings.CLOCK_SPEED]
int 0x30 ## Print Clock speed
mov R10, 0x0A
mov R9, $_hz_str
int 0x30 ## Print hz label
mov R10, 0x02
int 0x30 ## Print New Line
mov R9, $_bios_logo_2_line_4
mov R10, 0x0A
int 0x30
mov R10, 0x08 ## Print and flush buffer
int 0x30
mov R10, 0x0A
mov R9, $_mem_str
int 0x30 ## Print Memory label
mov R10, 0x05
mov R9, [CMOS_Settings.MEM_START]
int 0x30 ## Print Memory start
mov R10, 0x06
mov R9, 47
int 0x30 ## Print '/' character
mov R10, 0x05
mov R9, [CMOS_Settings.MEM_SIZE]
int 0x30 ## Print Memory size
mov R10, 0x0A
mov R9, $_byte_str
int 0x30 ## Print bytes label
mov R10, 0x02
int 0x30 ## Print New Line
mov R9, $_bios_logo_2_line_5
mov R7, 4
mov ACC, 19
_print_machine_info_logo_loop:
inc R7
mov R10, 0x0A
int 0x30
addip R9, 54 ## 90 is the length of a line
mov R10, 0x08
int 0x30
mov R10, 0x02
int 0x30
jls $_print_machine_info_logo_loop, R7
ret
.fixed 4096, 0x00 ## BIOS Needs to be 4096 Bytes exactly

View file

@ -0,0 +1,109 @@
@guard _LOGO_SCREEN_DSS_
_print_logo_screen:
mov R9, $_bios_logo_2_line_2
mov R10, 0x0A
int 0x30
mov R9, $_bios_logo_2_line_2
mov R10, 0x0A
int 0x30
mov R10, 0x03
mov R9, $_bios_name
int 0x30 ## Print BIOS Name
mov R10, 0x04
mov R9, [$_bios_version_number_maj]
int 0x30 ## Print BIOS Version (Major)
mov R10, 0x01
mov R9, 46
int 0x30 ## Print '.' character
mov R10, 0x04
mov R9, [$_bios_version_number_min]
int 0x30 ## Print BIOS Version (Minor)
mov R10, 0x02
int 0x30 ## Print New Line
mov R9, $_bios_logo_2_line_3
mov R10, 0x0A
int 0x30
mov R10, 0x03
mov R9, $_clock_str
int 0x30 ## Print Clock label
mov R10, 0x04
mov R9, [CMOS_Settings.CLOCK_SPEED]
int 0x30 ## Print Clock speed
mov R10, 0x03
mov R9, $_hz_str
int 0x30 ## Print hz label
mov R10, 0x02
int 0x30 ## Print New Line
mov R9, $_bios_logo_2_line_4
mov R10, 0x0A
int 0x30
mov R10, 0x03
mov R9, $_mem_str
int 0x30 ## Print Memory label
mov R10, 0x04
mov R9, [CMOS_Settings.MEM_START]
int 0x30 ## Print Memory start
mov R10, 0x01
mov R9, 47
int 0x30 ## Print '/' character
mov R10, 0x04
mov R9, [CMOS_Settings.MEM_SIZE]
int 0x30 ## Print Memory size
mov R10, 0x03
mov R9, $_byte_str
int 0x30 ## Print bytes label
mov R10, 0x02
int 0x30 ## Print New Line
mov R9, $_bios_logo_2_line_5
mov R7, 4
mov ACC, 19
mov R10, 0x0B
int 0x30
_print_machine_info_logo_loop:
inc R7
mov R10, 0x0A
int 0x30
addip R9, 54 ## 90 is the length of a line
mov R10, 0x08
int 0x30
mov R10, 0x02
int 0x30
debug_break
jls $_print_machine_info_logo_loop, R7
mov R10, 0x0B
int 0x30
ret

View file

@ -45,46 +45,26 @@ _set_interrupt_vector_entry_end:
_print_integer:
mov R1, 0
arg ACC
mov R3, 0 ## Used as boolean, 0 = positive, 1 = negative
jle $_print_integer_not_negative, 0
mov R3, 1
jeq $_print_integer_overflow_case, 0x8000
neg ACC
jmp $_print_integer_loop
_print_integer_overflow_case: ## Hardcoded for -32768 (0x8000)
push 56
push 54
push 55
push 50
push 51
mov R1, 5
jmp $_print_integer_loop_end
_print_integer_not_negative:
debug_break
jne $_print_integer_loop, 0
push 48 ## '0' ASCII is 48
inc R1
jmp $_print_integer_loop_end
_print_integer_loop:
jeq $_print_integer_loop_end, 0
div ACC, 10
mov R2, ACC
add RV, 48 ## '0' ASCII is 48
push ACC
divipu ACC, 10
addipu RV, 48
push RV
inc R1
mov ACC, R2
debug_break
jmp $_print_integer_loop
_print_integer_loop_end:
mov ACC, R3
jne $_print_integer_no_sign, 1
push 45 ## '-' ASCII is 45
inc R1
_print_integer_no_sign:
pop R9
dec R1
movb [VGA_Registers.TEXT_SINGLE_CHAR], R9
movb [VGA_Registers.SIGNAL], reg(S_REG_1)
mov ACC, R1
jne $_print_integer_no_sign, 0
jne $_print_integer_loop_end, 0
ret

View file

@ -10,19 +10,30 @@
$string "Hello World!!"
.code
mov R10, 0x00
mov R9, $_text_entered_handler
mov R8, 0xA2
int 0x20
int 0x20 ## Enable text entered handler
mov R10, 0x00
mov R9, $_key_pressed_handler
mov R8, 0xA0
int 0x20
int 0x20 ## Enable key pressed handler
mov R10, 0x0B
int 0x30 ## Invert colors
mov R10, 0x01
mov R9, 62
int 0x30
int 0x30 ## Print first prompt char
mov R10, 0x0B
int 0x30 ## Invert colors
mov R10, 0x01
mov R9, 32
int 0x30 ## Print space
mov R1, 0 ## Zero the counter
@ -59,7 +70,6 @@ no_clear_screen:
jmp $infinite_loop ## jump to the beginning of infinite loop
hlt
_text_entered_handler:
mov R9, [0x1282]
mov R10, 0x01
@ -72,9 +82,16 @@ _key_pressed_handler:
jne $_key_pressed_handler_end, 13
mov R10, 0x02
int 0x30
mov R10, 0x0B
int 0x30 ## Invert colors
mov R10, 0x01
mov R9, 62
int 0x30
mov R10, 0x0B
int 0x30 ## Invert colors
mov R10, 0x01
mov R9, 32
int 0x30
jmp $_key_pressed_handler_end
_key_pressed_handler_backspace:
debug_break

View file

@ -17,7 +17,7 @@ if [ $? -eq 0 ]; then
/bin/bash ./load_mbr
cd ..
printf "${green}Compiling Test Program...\n"
./dasm dss/newTest.dss -o newTest.bin --extmov --save-disassembly disassembly/newTest.dds --verbose
./dasm dss/newTest.dss -o newTest.bin --extmov --extalu --save-disassembly disassembly/newTest.dds --verbose
printf "\n${green}Running Application...\n\n${clear}"
./ddb config/testMachine.dvm --force-load newTest.bin 0x00 --verbose-load
cp dragon/disk1.dr ../extra/dragon/disk1.dr

View file

@ -17,7 +17,7 @@ if [ $? -eq 0 ]; then
/bin/bash ./load_mbr
cd ..
printf "${green}Compiling Test Program...\n"
./dasm dss/newTest.dss -o newTest.bin --extmov --save-disassembly disassembly/newTest.dds --verbose
./dasm dss/newTest.dss -o newTest.bin --extmov --extalu --save-disassembly disassembly/newTest.dds --verbose
printf "\n${green}Running Application...\n\n${clear}"
./dvm config/testMachine.dvm --force-load newTest.bin 0x00
cp dragon/disk1.dr ../extra/dragon/disk1.dr

View file

@ -6,5 +6,5 @@ clear='\033[0m'
printf "${green}Reloading BIOS...\n${clear}"
cd ..
cp ../extra/dss/bios/* ./dss/bios/
./dasm dss/bios/entry.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose --save-exports
./dasm dss/bios/entry.dss -o dragon/bios.bin --extalu --save-disassembly disassembly/bios.dds --verbose --save-exports
cp dragon/bios.bin ../extra/dragon/bios.bin

View file

@ -150,6 +150,8 @@ namespace dragon
}
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")
@ -178,7 +180,10 @@ namespace dragon
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 the <extmov> CPU extension.").reset().nl();
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();
@ -1303,6 +1308,64 @@ namespace dragon
opEdit.trim();
int16_t word = 0x0000;
auto st = opEdit.tokenize(",");
if (STDVEC_CONTAINS(cpuExtensions, "extalu"))
{
auto st = opEdit.tokenize(",");
if (instEdit == "addipu" || instEdit == "subipu" || instEdit == "mulipu" || instEdit == "divipu" || instEdit == "addip" || instEdit == "subip" || instEdit == "mulip" || instEdit == "divip")
{
m_code.push_back(data::OpCodes::Ext02);
m_code.push_back(0x00);
eOperandType opType = parseOperand(st.next(), word);
if (opType != eOperandType::Register)
{
std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n";
exit(0);
return;
}
m_code.push_back((uint8_t)word);
opType = parseOperand(st.next(), word);
if (opType == eOperandType::Immediate)
{
if (instEdit == "addip") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::addip_imm_in_reg;
else if (instEdit == "subip") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::subip_imm_in_reg;
else if (instEdit == "mulip") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::mulip_imm_in_reg;
else if (instEdit == "divip") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::divip_imm_in_reg;
else if (instEdit == "addipu") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::addipu_imm_in_reg;
else if (instEdit == "subipu") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::subipu_imm_in_reg;
else if (instEdit == "mulipu") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::mulipu_imm_in_reg;
else if (instEdit == "divipu") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::divipu_imm_in_reg;
m_code.push_back((uint8_t)((word & 0xFF00) >> 8));
m_code.push_back((uint8_t)(word & 0x00FF));
}
else if (opType == eOperandType::Register)
{
if (instEdit == "addip") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::addip_reg_in_reg;
else if (instEdit == "subip") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::subip_reg_in_reg;
else if (instEdit == "mulip") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::mulip_reg_in_reg;
else if (instEdit == "divip") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::divip_reg_in_reg;
else if (instEdit == "addipu") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::addipu_reg_in_reg;
else if (instEdit == "subipu") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::subipu_reg_in_reg;
else if (instEdit == "mulipu") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::mulipu_reg_in_reg;
else if (instEdit == "divipu") m_code[m_code.size() - 2] = hw::cpuext::ExtAlu::OpCodes::divipu_reg_in_reg;
m_code.push_back((uint8_t)word);
}
else
{
std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Immediate or register required\n";
exit(0);
return;
}
return;
}
}
else if (instEdit == "addipu" || instEdit == "subipu" || instEdit == "mulipu" || instEdit == "divipu" || instEdit == "addip" || instEdit == "subip" || instEdit == "mulip" || instEdit == "divip")
{
std::cout << "ExtAlu instruction detected, please add '--extalu' flag to dasm.\n";
exit(0);
return;
}
if (instEdit == "mov")
{
m_code.push_back(0x00);
@ -1634,10 +1697,10 @@ namespace dragon
int16_t word2 = 0x0000;
int16_t word3 = 0x0000;
auto st = opEdit.tokenize(",");
m_code.push_back(data::OpCodes::Ext01);
m_code.push_back(0x00);
if (instEdit == "omov")
{
m_code.push_back(data::OpCodes::Ext01);
m_code.push_back(0x00);
if (st.count() != 3)
{
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
@ -1793,6 +1856,8 @@ namespace dragon
}
else if (instEdit == "omovb")
{
m_code.push_back(data::OpCodes::Ext01);
m_code.push_back(0x00);
if (st.count() != 3)
{
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
@ -1946,6 +2011,8 @@ namespace dragon
}
else if (instEdit == "movo")
{
m_code.push_back(data::OpCodes::Ext01);
m_code.push_back(0x00);
if (st.count() != 3)
{
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
@ -2097,6 +2164,8 @@ namespace dragon
}
else if (instEdit == "movbo")
{
m_code.push_back(data::OpCodes::Ext01);
m_code.push_back(0x00);
if (st.count() != 3)
{
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
@ -2246,16 +2315,13 @@ namespace dragon
return;
}
}
else
{
std::cout << "Unknown instruction; " << line << " (" << instEdit << ")\n";
exit(0);
}
return;
}
else if (instEdit == "omov" || instEdit == "omovb" || instEdit == "movo" || instEdit == "movbo")
{
std::cout << "ExtMov instruction detected, please add '--extmov' flag to dasm.\n";
exit(0);
return;
}
}
@ -2271,11 +2337,15 @@ namespace dragon
m_disassembly.insert(m_disassembly.begin(), { (uint16_t)(m_loadAddress + 3), "[----------DATA_SECTION----------]" });
m_disassembly.insert(m_disassembly.begin(), { m_loadAddress, ostd::String("jmp ").add(ostd::Utils::getHexStr(entryAddr, true, 2)) });
for (auto& d : m_symbolTable)
{
symbols.push_back(d.second);
for (int32_t i = 0; i < d.second.bytes.size(); i++)
newCode.push_back(0x00);
}
for (int32_t i = symbols.size() - 1; i >= 0; i--)
{
for (auto& dd : symbols[i].bytes)
newCode.push_back(dd);
for (int32_t j = 0; j < symbols[i].bytes.size(); j++)
newCode[symbols[i].address - m_loadAddress + j] = symbols[i].bytes[j];
}
for (auto& b : m_code)
newCode.push_back(b);

View file

@ -1038,10 +1038,13 @@ namespace dragon
auto& callStack = minfo.callStack;
int32_t level = -1;
ostd::String ch_ang_u = "";
ch_ang_u.addChar((unsigned char)218);
//TODO: Find a fix for the UTF characters
ch_ang_u.add("");
// ch_ang_u.addChar((unsigned char)218);
ostd::String ch_ang_l = "|";
ostd::String ch_ang_d = "";
ch_ang_d.addChar((unsigned char)192);
ch_ang_d.add("");
// ch_ang_d.addChar((unsigned char)192);
for (auto& call : callStack)
{
ostd::String call_info = call.info.new_trim().toLower();
@ -1056,7 +1059,7 @@ namespace dragon
}
else if (call_info == "hw int")
{
call_str = ch_ang_u + "hwi " + ostd::Utils::getHexStr(call.addr, true, 1);
call_str = ch_ang_u + "hwi " + ostd::Utils::getHexStr(call.addr, true, 1) + " (" + data::InterruptCodes::getInterruptName(call.addr) + ")";
level++;
}
else if (call_info == "ret")
@ -1095,7 +1098,11 @@ namespace dragon
rgx.fg("\\$\\w+", "Green"); //Labels
out.fg(ostd::ConsoleColors::BrightGray).p("|").reset();
out.fg(ostd::ConsoleColors::Magenta).p(ostd::Utils::getHexStr(call.inst_addr, true, 2));
if (call.interrupts_disabled)
out.fg(ostd::ConsoleColors::BrightGray);
else
out.fg(ostd::ConsoleColors::Magenta);
out.p(ostd::Utils::getHexStr(call.inst_addr, true, 2));
out.fg(ostd::ConsoleColors::BrightGray).p("| > ").reset();
out.pStyled(rgx).nl().reset();

View file

@ -25,6 +25,9 @@ namespace dragon
drawCharacter((uint8_t*)screenPixels, screenWidth, screenHeight, (uint8_t*)fontPixels, x, y, c, color, background);
x += FONT_CHAR_W;
}
s_cursor_pos_x = x;
if (s_cursor_pos_x >= CONSOLE_CHARS_H)
s_cursor_pos_x = 0;
return true;
}

View file

@ -26,5 +26,7 @@ namespace dragon
inline static constexpr int32_t FONT_H_CHARS = 16;
inline static constexpr int32_t CONSOLE_CHARS_H = 90;
inline static constexpr int32_t CONSOLE_CHARS_V = 21;
inline static int8_t s_cursor_pos_x = 0;
};
}

View file

@ -464,6 +464,232 @@ namespace dragon
return true;
}
ostd::String ExtAlu::getOpCodeString(uint8_t opCode)
{
switch (opCode)
{
case OpCodes::addipu_reg_in_reg: return m_name + "_addipu_reg_in_reg";
case OpCodes::addipu_imm_in_reg: return m_name + "_addipu_imm_in_reg";
case OpCodes::subipu_reg_in_reg: return m_name + "_subipu_reg_in_reg";
case OpCodes::subipu_imm_in_reg: return m_name + "_subipu_imm_in_reg";
case OpCodes::mulipu_reg_in_reg: return m_name + "_mulipu_reg_in_reg";
case OpCodes::mulipu_imm_in_reg: return m_name + "_mulipu_imm_in_reg";
case OpCodes::divipu_reg_in_reg: return m_name + "_divipu_reg_in_reg";
case OpCodes::divipu_imm_in_reg: return m_name + "_divipu_imm_in_reg";
case OpCodes::addip_reg_in_reg: return m_name + "_addip_reg_in_reg";
case OpCodes::addip_imm_in_reg: return m_name + "_addip_imm_in_reg";
case OpCodes::subip_reg_in_reg: return m_name + "_subip_reg_in_reg";
case OpCodes::subip_imm_in_reg: return m_name + "_subip_imm_in_reg";
case OpCodes::mulip_reg_in_reg: return m_name + "_mulip_reg_in_reg";
case OpCodes::mulip_imm_in_reg: return m_name + "_mulip_imm_in_reg";
case OpCodes::divip_reg_in_reg: return m_name + "_divip_reg_in_reg";
case OpCodes::divip_imm_in_reg: return m_name + "_divip_imm_in_reg";
default: return m_name + "_UNKNOWN_INST";
}
}
uint8_t ExtAlu::getInstructionSIze(uint8_t opCode)
{
switch (opCode)
{
case OpCodes::addipu_reg_in_reg: return 3;
case OpCodes::addipu_imm_in_reg: return 4;
case OpCodes::subipu_reg_in_reg: return 3;
case OpCodes::subipu_imm_in_reg: return 4;
case OpCodes::mulipu_reg_in_reg: return 3;
case OpCodes::mulipu_imm_in_reg: return 4;
case OpCodes::divipu_reg_in_reg: return 3;
case OpCodes::divipu_imm_in_reg: return 4;
case OpCodes::addip_reg_in_reg: return 3;
case OpCodes::addip_imm_in_reg: return 4;
case OpCodes::subip_reg_in_reg: return 3;
case OpCodes::subip_imm_in_reg: return 4;
case OpCodes::mulip_reg_in_reg: return 3;
case OpCodes::mulip_imm_in_reg: return 4;
case OpCodes::divip_reg_in_reg: return 3;
case OpCodes::divip_imm_in_reg: return 4;
default: return 0;
}
}
bool ExtAlu::execute(VirtualCPU& vcpu)
{
auto& mem = DragonRuntime::memMap;
uint8_t inst = vcpu.fetch8();
switch (inst)
{
case OpCodes::addipu_reg_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint8_t src_reg = vcpu.fetch8();
uint16_t dest_val = vcpu.readRegister(dest_reg);
uint16_t src_val = vcpu.readRegister(src_reg);
uint16_t res = dest_val + src_val;
vcpu.writeRegister16(dest_reg, (int16_t)res);
}
break;
case OpCodes::addipu_imm_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint16_t src_val = vcpu.fetch16();
uint16_t dest_val = vcpu.readRegister(dest_reg);
uint16_t res = dest_val + src_val;
vcpu.writeRegister16(dest_reg, (int16_t)res);
}
break;
case OpCodes::subipu_reg_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint8_t src_reg = vcpu.fetch8();
uint16_t dest_val = vcpu.readRegister(dest_reg);
uint16_t src_val = vcpu.readRegister(src_reg);
uint16_t res = dest_val - src_val;
vcpu.writeRegister16(dest_reg, (int16_t)res);
}
break;
case OpCodes::subipu_imm_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint16_t src_val = vcpu.fetch16();
uint16_t dest_val = vcpu.readRegister(dest_reg);
uint16_t res = dest_val - src_val;
vcpu.writeRegister16(dest_reg, (int16_t)res);
}
break;
case OpCodes::mulipu_reg_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint8_t src_reg = vcpu.fetch8();
uint16_t dest_val = vcpu.readRegister(dest_reg);
uint16_t src_val = vcpu.readRegister(src_reg);
uint16_t res = dest_val * src_val;
vcpu.writeRegister16(dest_reg, (int16_t)res);
}
break;
case OpCodes::mulipu_imm_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint16_t src_val = vcpu.fetch16();
uint16_t dest_val = vcpu.readRegister(dest_reg);
uint16_t res = dest_val * src_val;
vcpu.writeRegister16(dest_reg, (int16_t)res);
}
break;
case OpCodes::divipu_reg_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint8_t src_reg = vcpu.fetch8();
uint16_t dest_val = vcpu.readRegister(dest_reg);
uint16_t src_val = vcpu.readRegister(src_reg);
uint16_t res = dest_val / src_val;
uint16_t rv = dest_val % src_val;
vcpu.writeRegister16(dest_reg, (int16_t)res);
vcpu.writeRegister16(data::Registers::RV, (int16_t)rv);
}
break;
case OpCodes::divipu_imm_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint16_t src_val = vcpu.fetch16();
uint16_t dest_val = vcpu.readRegister(dest_reg);
uint16_t res = dest_val / src_val;
uint16_t rv = dest_val % src_val;
vcpu.writeRegister16(dest_reg, (int16_t)res);
vcpu.writeRegister16(data::Registers::RV, (int16_t)rv);
}
break;
case OpCodes::addip_reg_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint8_t src_reg = vcpu.fetch8();
int16_t dest_val = vcpu.readRegister(dest_reg);
int16_t src_val = vcpu.readRegister(src_reg);
int16_t res = dest_val + src_val;
vcpu.writeRegister16(dest_reg, res);
}
break;
case OpCodes::addip_imm_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint16_t src_val = vcpu.fetch16();
int16_t dest_val = vcpu.readRegister(dest_reg);
int16_t res = dest_val + src_val;
vcpu.writeRegister16(dest_reg, res);
}
break;
case OpCodes::subip_reg_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint8_t src_reg = vcpu.fetch8();
int16_t dest_val = vcpu.readRegister(dest_reg);
int16_t src_val = vcpu.readRegister(src_reg);
int16_t res = dest_val - src_val;
vcpu.writeRegister16(dest_reg, res);
}
break;
case OpCodes::subip_imm_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint16_t src_val = vcpu.fetch16();
int16_t dest_val = vcpu.readRegister(dest_reg);
int16_t res = dest_val - src_val;
vcpu.writeRegister16(dest_reg, res);
}
break;
case OpCodes::mulip_reg_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint8_t src_reg = vcpu.fetch8();
int16_t dest_val = vcpu.readRegister(dest_reg);
int16_t src_val = vcpu.readRegister(src_reg);
int16_t res = dest_val * src_val;
vcpu.writeRegister16(dest_reg, res);
}
break;
case OpCodes::mulip_imm_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint16_t src_val = vcpu.fetch16();
int16_t dest_val = vcpu.readRegister(dest_reg);
int16_t res = dest_val * src_val;
vcpu.writeRegister16(dest_reg, res);
}
break;
case OpCodes::divip_reg_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint8_t src_reg = vcpu.fetch8();
int16_t dest_val = vcpu.readRegister(dest_reg);
int16_t src_val = vcpu.readRegister(src_reg);
int16_t res = dest_val / src_val;
int16_t rv = dest_val % src_val;
vcpu.writeRegister16(dest_reg, res);
vcpu.writeRegister16(data::Registers::RV, rv);
}
break;
case OpCodes::divip_imm_in_reg:
{
uint8_t dest_reg = vcpu.fetch8();
uint16_t src_val = vcpu.fetch16();
int16_t dest_val = vcpu.readRegister(dest_reg);
int16_t res = dest_val / src_val;
int16_t rv = dest_val % src_val;
vcpu.writeRegister16(dest_reg, res);
vcpu.writeRegister16(data::Registers::RV, rv);
}
break;
default:
{
//TODO: Error
return false;
}
}
return true;
}
}
}
}

View file

@ -59,6 +59,38 @@ namespace dragon
uint8_t getInstructionSIze(uint8_t opCode) override;
bool execute(VirtualCPU& vcpu) override;
};
}
class ExtAlu : public data::CPUExtension
{
public: class OpCodes
{
public:
inline static constexpr uint8_t addipu_reg_in_reg = 0x10;
inline static constexpr uint8_t addipu_imm_in_reg = 0x11;
inline static constexpr uint8_t subipu_reg_in_reg = 0x12;
inline static constexpr uint8_t subipu_imm_in_reg = 0x13;
inline static constexpr uint8_t mulipu_reg_in_reg = 0x14;
inline static constexpr uint8_t mulipu_imm_in_reg = 0x15;
inline static constexpr uint8_t divipu_reg_in_reg = 0x16;
inline static constexpr uint8_t divipu_imm_in_reg = 0x17;
inline static constexpr uint8_t addip_reg_in_reg = 0x20;
inline static constexpr uint8_t addip_imm_in_reg = 0x21;
inline static constexpr uint8_t subip_reg_in_reg = 0x22;
inline static constexpr uint8_t subip_imm_in_reg = 0x23;
inline static constexpr uint8_t mulip_reg_in_reg = 0x24;
inline static constexpr uint8_t mulip_imm_in_reg = 0x25;
inline static constexpr uint8_t divip_reg_in_reg = 0x26;
inline static constexpr uint8_t divip_imm_in_reg = 0x27;
};
public:
inline ExtAlu(void) : data::CPUExtension(data::OpCodes::Ext02, "extalu") { }
ostd::String getOpCodeString(uint8_t opCode) override;
uint8_t getInstructionSIze(uint8_t opCode) override;
bool execute(VirtualCPU& vcpu) override;
};
}
}
}

View file

@ -174,6 +174,7 @@ namespace dragon
interruptData.info = "HW INT";
interruptData.addr = intValue;
interruptData.inst_addr = 0x0000;
interruptData.interrupts_disabled = !readFlag(data::Flags::InterruptsEnabled);
ostd::SignalHandler::emitSignal(DragonRuntime::SignalListener::Signal_HardwareInterruptOccurred, ostd::tSignalPriority::RealTime, interruptData);
}
}

View file

@ -20,7 +20,7 @@ namespace dragon
int16_t readRegister(uint8_t reg);
int16_t writeRegister16(uint8_t reg, int16_t value);
int8_t writeRegister8(uint8_t reg, int8_t value);
//TODO: Implement writeRegister8 and writeRegister16 functions (maybe for readRegister aswell)
//TODO: Implement readRegister8 and readRegister16 functions
int8_t fetch8(void);
int16_t fetch16(void);

View file

@ -17,13 +17,22 @@ namespace dragon
void VirtualDisplay::onRender(void)
{
auto& config = DragonRuntime::machine_config;
auto& mem = DragonRuntime::memMap;
uint16_t vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
uint8_t invert_colors = mem.read8(vga_addr + tRegisters::TextSingleInvertColors);
if (m_refreshScreen)
{
m_renderer.clear(config.singleColor_background);
if (invert_colors == 0)
m_renderer.clear(config.singleColor_background);
else
m_renderer.clear(config.singleColor_foreground);
for (int32_t i = 0; i < m_singleTextLines.size(); i++)
{
auto& line = m_singleTextLines[i];
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground);
if (invert_colors == 0)
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
else
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
}
m_refreshScreen = false;
}
@ -82,10 +91,16 @@ namespace dragon
void VirtualDisplay::single_text_add_char_to_line(char c)
{
auto& config = DragonRuntime::machine_config;
auto& mem = DragonRuntime::memMap;
uint16_t vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
uint8_t invert_colors = mem.read8(vga_addr + tRegisters::TextSingleInvertColors);
if (m_singleTextLines.size() == 0)
{
m_singleTextLines.push_back(ostd::String().addChar(c));
RawTextRenderer::drawString(ostd::String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground);
if (invert_colors == 0)
RawTextRenderer::drawString(ostd::String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
else
RawTextRenderer::drawString(ostd::String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
return;
}
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
@ -97,12 +112,18 @@ namespace dragon
{
m_singleTextLines.push_back(ostd::String().addChar(c));
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground);
if (invert_colors == 0)
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
else
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
}
else
{
line.addChar(c);
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground);
if (invert_colors == 0)
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
else
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
}
}
else return;

View file

@ -14,6 +14,7 @@ namespace dragon
inline static constexpr uint8_t VideoMode = 0x00;
inline static constexpr uint8_t Signal = 0x03;
inline static constexpr uint8_t TextSingleCharacter = 0x04;
inline static constexpr uint8_t TextSingleInvertColors = 0x05;
};
public: struct tVideoModeValues
{

View file

@ -45,6 +45,10 @@ namespace dragon
{
config.cpuext_list[ext_nr++] = new hw::cpuext::ExtMov;
}
else if (lineEdit == "extalu")
{
config.cpuext_list[ext_nr++] = new hw::cpuext::ExtAlu;
}
else continue; //TODO: Warning
}
}
@ -68,6 +72,23 @@ namespace dragon
lineEdit = tokens.next();
config.singleColor_background.set(lineEdit);
}
else if (lineEdit == "clock_rate_sec")
{
lineEdit = tokens.next();
lineEdit.trim().toLower();
if (!lineEdit.isNumeric()) continue; //TODO: Error
config.clock_rate_sec = lineEdit.toInt();
}
else if (lineEdit == "fixed_clock")
{
lineEdit = tokens.next();
lineEdit.trim().toLower();
if (lineEdit == "true")
config.fixed_clock = true;
else if (lineEdit == "false")
config.fixed_clock = false;
else continue; //TODO: Error
}
else continue; //TODO: Warning
}
return validate_machine_config(config);

View file

@ -10,6 +10,8 @@ namespace dragon
{
std::map<int32_t, ostd::String> vdisk_paths;
std::map<int32_t, data::CPUExtension*> cpuext_list;
int32_t clock_rate_sec { 500 };
bool fixed_clock { true };
ostd::String bios_path;
ostd::String cmos_path;
ostd::Color singleColor_background;

View file

@ -280,14 +280,8 @@ namespace dragon
}
memMap.mapDevice(ram, dragon::data::MemoryMapAddresses::Memory_Start, dragon::data::MemoryMapAddresses::Memory_End, false, "RAM");
//Default VideoBios Colors
uint8_t default_bios_video_color = 0x4;
if (verbose)
{
out.fg(ostd::ConsoleColors::Magenta).p(" Initializing vCPU reset sequence:").nl();
// out.p(" BIOSVideo default colors: ").p(ostd::Utils::getHexStr(default_bios_video_color).cpp_str()).nl();
}
// memMap.write8(dragon::data::MemoryMapAddresses::BIOSVideo_Start, default_bios_video_color);
uint16_t reset_ip_addr = 0x0000;
if (verbose)
@ -314,6 +308,21 @@ namespace dragon
}
}
if (verbose)
{
out.fg(ostd::ConsoleColors::BrightYellow).p(" Fixed clock enabled: ").p(STR_BOOL(machine_config.fixed_clock)).nl();
if (machine_config.fixed_clock)
out.fg(ostd::ConsoleColors::BrightYellow).p(" Clock speed: ").p(machine_config.clock_rate_sec).p(" Hz").nl();
}
vCMOS.write16(data::CMOSRegisters::MemoryStart, data::MemoryMapAddresses::Memory_Start);
vCMOS.write16(data::CMOSRegisters::MemorySize, data::MemoryMapAddresses::Memory_End);
vCMOS.write16(data::CMOSRegisters::ClockSpeed, machine_config.clock_rate_sec);
if (verbose)
out.fg(ostd::ConsoleColors::BrightYellow).p(" Loading CMOS Machine info").nl();
out.nl().nl();
s_trackMachineInfo = trackMachineInfoDiff;
s_trackCallStack = trackCallStack;
@ -327,10 +336,14 @@ namespace dragon
void DragonRuntime::runMachine(void)
{
double clock_speed_us = 2000;
double clock_speed_us = 1000000.0 / machine_config.clock_rate_sec;
double acc = 0;
uint64_t avg_count = 0;
uint64_t _time = 0;
double avg_tot = 0;
ostd::Timer clock_timer;
bool running = true;
bool fixed_clock = machine_config.fixed_clock;
while (running || vDiskInterface.isBusy())
{
clock_timer.startCount(ostd::eTimeUnits::Microseconds);
@ -346,15 +359,17 @@ namespace dragon
processErrors();
break;
}
uint64_t _time = clock_timer.endCount();
if (_time < clock_speed_us)
ostd::Utils::sleep(clock_speed_us - _time, ostd::eTimeUnits::Microseconds);
acc++;
if (acc == 500)
{
std::cout << _time << "\n";
avg_count++;
avg_tot += _time;
s_avgInstTime = (uint64_t)std::round(avg_tot / avg_count);
acc = 0;
}
_time = clock_timer.endCount();
acc++;
if (_time < clock_speed_us && fixed_clock)
ostd::Utils::sleep(clock_speed_us - _time, ostd::eTimeUnits::Microseconds);
}
}
@ -485,26 +500,26 @@ namespace dragon
if (inst == data::OpCodes::CallImm)
{
uint16_t call_addr = memMap.read16(instAddr + 1);
minfo.callStack.push_back({ "CALL IMM", call_addr, instAddr });
minfo.callStack.push_back({ "CALL IMM", call_addr, instAddr, !interrupts_enabled });
}
else if (inst == data::OpCodes::CallReg)
{
uint8_t reg_addr = memMap.read8(instAddr + 1);
uint16_t call_addr = cpu.readRegister(reg_addr);
minfo.callStack.push_back({ "CALL REG", call_addr, instAddr });
minfo.callStack.push_back({ "CALL REG", call_addr, instAddr, !interrupts_enabled });
}
else if (interrupts_enabled && inst == data::OpCodes::Int)
{
uint8_t int_num = memMap.read8(instAddr + 1);
minfo.callStack.push_back({ "INT", int_num, instAddr });
minfo.callStack.push_back({ "INT", int_num, instAddr, !interrupts_enabled });
}
else if (inst == data::OpCodes::Ret)
{
minfo.callStack.push_back({ "RET", 0x0000, instAddr });
minfo.callStack.push_back({ "RET", 0x0000, instAddr, !interrupts_enabled });
}
else if (interrupts_enabled && inst == data::OpCodes::RetInt)
{
minfo.callStack.push_back({ "RET INT", 0x0000, instAddr });
minfo.callStack.push_back({ "RET INT", 0x0000, instAddr, !interrupts_enabled });
}
}

View file

@ -30,10 +30,11 @@ namespace dragon
public: struct tCallInfo : public ostd::BaseObject
{
inline tCallInfo(void) { }
inline tCallInfo(const ostd::String& _info, uint16_t _addr, uint16_t _inst_addr) : info(_info), addr(_addr), inst_addr(_inst_addr) { }
inline tCallInfo(const ostd::String& _info, uint16_t _addr, uint16_t _inst_addr, bool ints_disabled) : info(_info), addr(_addr), inst_addr(_inst_addr), interrupts_disabled(ints_disabled) { }
ostd::String info;
uint16_t addr;
uint16_t inst_addr;
bool interrupts_disabled;
};
public: struct tCommandLineArgs
{
@ -101,6 +102,7 @@ namespace dragon
inline static const tMachineDebugInfo& getMachineInfoDiff(void) { return s_machineInfo; }
inline static bool hasError(void) { return data::ErrorHandler::hasError(); }
inline static ostd::ConsoleOutputHandler& output(void) { return out; }
inline static uint64_t getAvgClockSpeed(void) { return (uint64_t)std::round(1000000.0 / s_avgInstTime); }
private:
static void __get_machine_footprint(tMachineDebugInfo* machineInfo, std::vector<uint16_t> trackedAddresses, bool previous);
@ -129,12 +131,15 @@ namespace dragon
inline static tMachineConfig machine_config;
inline static uint64_t s_avgInstTime { 0 };
private:
inline static tMachineDebugInfo s_machineInfo;
inline static bool s_trackMachineInfo { false };
inline static bool s_trackCallStack { false };
inline static SignalListener s_signalListener;
public:
inline static const int32_t RETURN_VAL_CLOSE_DEBUGGER = 128;
inline static const int32_t RETURN_VAL_CLOSE_RUNTIME = 256;

View file

@ -194,6 +194,28 @@ namespace dragon
inline static constexpr uint8_t KeyPressed = 0xA0;
inline static constexpr uint8_t KeyReleased = 0xA1;
inline static constexpr uint8_t TextEntered = 0xA2;
inline static ostd::String getInterruptName(uint8_t code)
{
switch (code)
{
case DiskInterfaceFFinished: return "Disk_Interface_Finished";
case KeyPressed: return "Key_Pressed";
case KeyReleased: return "Key_Released";
case TextEntered: return "Text_Entered";
default: return "UNKNOWN";
}
return "UNKNOWN";
}
};
class CMOSRegisters
{
public:
inline static constexpr uint8_t MemoryStart = 0x00;
inline static constexpr uint8_t MemorySize = 0x02;
inline static constexpr uint8_t ClockSpeed = 0x04;
inline static constexpr uint8_t BootDisk = 0x10;
};
class CPUExtension