Implemented ExtAlu CPU extension + Bios logo
This commit is contained in:
parent
f40ae0a036
commit
f256b901a1
32 changed files with 807 additions and 103 deletions
4
.vscode/c_cpp_properties.json
vendored
4
.vscode/c_cpp_properties.json
vendored
|
|
@ -9,7 +9,7 @@
|
||||||
"defines": [],
|
"defines": [],
|
||||||
"compilerPath": "/usr/bin/clang++",
|
"compilerPath": "/usr/bin/clang++",
|
||||||
"cStandard": "c17",
|
"cStandard": "c17",
|
||||||
"cppStandard": "c++20",
|
"cppStandard": "c++23",
|
||||||
"intelliSenseMode": "linux-clang-x64"
|
"intelliSenseMode": "linux-clang-x64"
|
||||||
//"compileCommands": "${workspaceFolder}/compile_commands.json"
|
//"compileCommands": "${workspaceFolder}/compile_commands.json"
|
||||||
},
|
},
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
"defines": [],
|
"defines": [],
|
||||||
"compilerPath": "C:\\msys64\\ucrt64\\bin\\clang++",
|
"compilerPath": "C:\\msys64\\ucrt64\\bin\\clang++",
|
||||||
"cStandard": "c17",
|
"cStandard": "c17",
|
||||||
"cppStandard": "c++20",
|
"cppStandard": "c++23",
|
||||||
"intelliSenseMode": "windows-clang-x64"
|
"intelliSenseMode": "windows-clang-x64"
|
||||||
//"compileCommands": "${workspaceFolder}/compile_commands.json"
|
//"compileCommands": "${workspaceFolder}/compile_commands.json"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
cmake_minimum_required(VERSION 3.18)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
project(${PROJ_NAME} LANGUAGES C CXX)
|
project(${PROJ_NAME} LANGUAGES C CXX)
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
file(STRINGS "./build.nr" BUILD_NUMBER)
|
file(STRINGS "./build.nr" BUILD_NUMBER)
|
||||||
#-----------------------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
2
build.nr
2
build.nr
|
|
@ -1 +1 @@
|
||||||
1589
|
1590
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
Disks = dragon/disk1.dr
|
Disks = dragon/disk1.dr
|
||||||
Bios = dragon/bios.bin
|
Bios = dragon/bios.bin
|
||||||
CMOS = dragon/cmos.dr
|
CMOS = dragon/cmos.dr
|
||||||
cpuext = extmov
|
cpuext = extmov, extalu
|
||||||
|
fixed_clock = false
|
||||||
|
clock_rate_sec = 512
|
||||||
|
|
||||||
SingleColor_foreground = #009900FF
|
SingleColor_foreground = #009900FF
|
||||||
SingleColor_background = #111111FF
|
SingleColor_background = #111111FF
|
||||||
|
|
@ -7,7 +7,13 @@
|
||||||
0x0FFF
|
0x0FFF
|
||||||
-------
|
-------
|
||||||
0x1000 CMOS (128 Bytes) (write to this section is only allowed in BIOS Mode)
|
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
|
BootDisk: 0x0010
|
||||||
|
|
||||||
|
ICC_
|
||||||
|
ICC_OutputAddr: (2 bytes) 0x007E
|
||||||
0x107F
|
0x107F
|
||||||
-------
|
-------
|
||||||
0x1080 INTERRUPT VECTOR (512 Bytes)
|
0x1080 INTERRUPT VECTOR (512 Bytes)
|
||||||
|
|
@ -90,7 +96,8 @@
|
||||||
|
|
||||||
0xE0: Refresh Screen
|
0xE0: Refresh Screen
|
||||||
0xE1: Clear 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
|
0x16FF
|
||||||
-------
|
-------
|
||||||
0x1700 GENERIC SERIAL INTERFACE (64 Bytes)
|
0x1700 GENERIC SERIAL INTERFACE (64 Bytes)
|
||||||
|
|
@ -125,6 +132,7 @@ BIOS Specific - Software Interrupts:
|
||||||
0x08: Print buffer and flush in Text Single Mode
|
0x08: Print buffer and flush in Text Single Mode
|
||||||
0x09: Flush buffer 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)
|
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
|
0xE0: Refresh Screen
|
||||||
0xE1: Clear Screen
|
0xE1: Clear Screen
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
Text visualization for hardware interrupts (in call-tree view)
|
#***Inverted Colors in Text-Single-Color
|
||||||
Inverted Colors in Text-Single-Color
|
#***show where interrupts are disabled (in call-tree view)
|
||||||
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 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
|
#***Add "Extended mov" instruction set
|
||||||
#***Remove old offset mov
|
#***Remove old offset mov
|
||||||
#***Implelemnt extmov mnemonics in dasm:
|
#***Implelemnt extmov mnemonics in dasm:
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -13,6 +13,9 @@
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@group CMOS_Settings
|
@group CMOS_Settings
|
||||||
|
MEM_START { MemoryAddresses.CMOS + 0x0000 }
|
||||||
|
MEM_SIZE { MemoryAddresses.CMOS + 0x0002 }
|
||||||
|
CLOCK_SPEED { MemoryAddresses.CMOS + 0x0004 }
|
||||||
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
|
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
@ -34,6 +37,7 @@
|
||||||
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
|
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
|
||||||
SIGNAL { MemoryAddresses.VGA + 0x0003 }
|
SIGNAL { MemoryAddresses.VGA + 0x0003 }
|
||||||
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
|
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
|
||||||
|
TEXT_SIGNLE_INVERT { MemoryAddresses.VGA + 0x0005 }
|
||||||
|
|
||||||
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
|
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
|
||||||
@end
|
@end
|
||||||
|
|
@ -73,6 +77,39 @@
|
||||||
## ===============================================================================================
|
## ===============================================================================================
|
||||||
|
|
||||||
.data
|
.data
|
||||||
$_bios_name "DragonBIOS"
|
|
||||||
$_bios_version_number_maj 0x00, 0x00
|
$_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 " |___/ "
|
||||||
|
|
@ -52,6 +52,7 @@ _int_30_handler:
|
||||||
jeq $_int_30_print_buffer_and_flush_text_single, 0x0008
|
jeq $_int_30_print_buffer_and_flush_text_single, 0x0008
|
||||||
jeq $_int_30_flush_buffer_text_single, 0x0009
|
jeq $_int_30_flush_buffer_text_single, 0x0009
|
||||||
jeq $_int_30_store_string_text_single, 0x000A
|
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_clear_screen, 0x00E0
|
||||||
jeq $_int_30_refresh_screen, 0x00E1
|
jeq $_int_30_refresh_screen, 0x00E1
|
||||||
jmp $_int_30_end
|
jmp $_int_30_end
|
||||||
|
|
@ -105,6 +106,14 @@ _int_30_store_string_text_single:
|
||||||
movb ACC, *R9
|
movb ACC, *R9
|
||||||
jne $_int_30_store_string_text_single, 0
|
jne $_int_30_store_string_text_single, 0
|
||||||
jmp $_int_30_end
|
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:
|
_int_30_clear_screen:
|
||||||
|
|
|
||||||
|
|
@ -14,23 +14,8 @@
|
||||||
mov R8, 0x30 ## -Passing the interrupt's code to setup
|
mov R8, 0x30 ## -Passing the interrupt's code to setup
|
||||||
int 0x20 ## -Calling int 0x20 with 0x00 as parameter, to set new handler up
|
int 0x20 ## -Calling int 0x20 with 0x00 as parameter, to set new handler up
|
||||||
|
|
||||||
mov R10, 0x03
|
push 0
|
||||||
mov R9, $_bios_name
|
call $_print_machine_info
|
||||||
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
|
|
||||||
|
|
||||||
## MBR Loading
|
## MBR Loading
|
||||||
and FL, 0b1111111111111110 ## Disable interrupts
|
and FL, 0b1111111111111110 ## Disable interrupts
|
||||||
|
|
@ -49,4 +34,134 @@
|
||||||
@include <drivers.dss>
|
@include <drivers.dss>
|
||||||
@include <utils.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
|
.fixed 4096, 0x00 ## BIOS Needs to be 4096 Bytes exactly
|
||||||
|
|
|
||||||
109
extra/dss/bios/logo_screen.dss
Normal file
109
extra/dss/bios/logo_screen.dss
Normal 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
|
||||||
|
|
@ -45,46 +45,26 @@ _set_interrupt_vector_entry_end:
|
||||||
_print_integer:
|
_print_integer:
|
||||||
mov R1, 0
|
mov R1, 0
|
||||||
arg ACC
|
arg ACC
|
||||||
mov R3, 0 ## Used as boolean, 0 = positive, 1 = negative
|
debug_break
|
||||||
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:
|
|
||||||
jne $_print_integer_loop, 0
|
jne $_print_integer_loop, 0
|
||||||
push 48 ## '0' ASCII is 48
|
push 48 ## '0' ASCII is 48
|
||||||
inc R1
|
inc R1
|
||||||
jmp $_print_integer_loop_end
|
jmp $_print_integer_loop_end
|
||||||
_print_integer_loop:
|
_print_integer_loop:
|
||||||
jeq $_print_integer_loop_end, 0
|
jeq $_print_integer_loop_end, 0
|
||||||
div ACC, 10
|
divipu ACC, 10
|
||||||
mov R2, ACC
|
addipu RV, 48
|
||||||
add RV, 48 ## '0' ASCII is 48
|
push RV
|
||||||
push ACC
|
|
||||||
inc R1
|
inc R1
|
||||||
mov ACC, R2
|
debug_break
|
||||||
jmp $_print_integer_loop
|
jmp $_print_integer_loop
|
||||||
_print_integer_loop_end:
|
_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
|
pop R9
|
||||||
dec R1
|
dec R1
|
||||||
movb [VGA_Registers.TEXT_SINGLE_CHAR], R9
|
movb [VGA_Registers.TEXT_SINGLE_CHAR], R9
|
||||||
movb [VGA_Registers.SIGNAL], reg(S_REG_1)
|
movb [VGA_Registers.SIGNAL], reg(S_REG_1)
|
||||||
mov ACC, R1
|
mov ACC, R1
|
||||||
jne $_print_integer_no_sign, 0
|
jne $_print_integer_loop_end, 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,30 @@
|
||||||
$string "Hello World!!"
|
$string "Hello World!!"
|
||||||
|
|
||||||
.code
|
.code
|
||||||
|
|
||||||
mov R10, 0x00
|
mov R10, 0x00
|
||||||
mov R9, $_text_entered_handler
|
mov R9, $_text_entered_handler
|
||||||
mov R8, 0xA2
|
mov R8, 0xA2
|
||||||
int 0x20
|
int 0x20 ## Enable text entered handler
|
||||||
|
|
||||||
mov R10, 0x00
|
mov R10, 0x00
|
||||||
mov R9, $_key_pressed_handler
|
mov R9, $_key_pressed_handler
|
||||||
mov R8, 0xA0
|
mov R8, 0xA0
|
||||||
int 0x20
|
int 0x20 ## Enable key pressed handler
|
||||||
|
|
||||||
|
mov R10, 0x0B
|
||||||
|
int 0x30 ## Invert colors
|
||||||
|
|
||||||
mov R10, 0x01
|
mov R10, 0x01
|
||||||
mov R9, 62
|
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
|
mov R1, 0 ## Zero the counter
|
||||||
|
|
@ -59,7 +70,6 @@ no_clear_screen:
|
||||||
jmp $infinite_loop ## jump to the beginning of infinite loop
|
jmp $infinite_loop ## jump to the beginning of infinite loop
|
||||||
hlt
|
hlt
|
||||||
|
|
||||||
|
|
||||||
_text_entered_handler:
|
_text_entered_handler:
|
||||||
mov R9, [0x1282]
|
mov R9, [0x1282]
|
||||||
mov R10, 0x01
|
mov R10, 0x01
|
||||||
|
|
@ -72,9 +82,16 @@ _key_pressed_handler:
|
||||||
jne $_key_pressed_handler_end, 13
|
jne $_key_pressed_handler_end, 13
|
||||||
mov R10, 0x02
|
mov R10, 0x02
|
||||||
int 0x30
|
int 0x30
|
||||||
|
mov R10, 0x0B
|
||||||
|
int 0x30 ## Invert colors
|
||||||
mov R10, 0x01
|
mov R10, 0x01
|
||||||
mov R9, 62
|
mov R9, 62
|
||||||
int 0x30
|
int 0x30
|
||||||
|
mov R10, 0x0B
|
||||||
|
int 0x30 ## Invert colors
|
||||||
|
mov R10, 0x01
|
||||||
|
mov R9, 32
|
||||||
|
int 0x30
|
||||||
jmp $_key_pressed_handler_end
|
jmp $_key_pressed_handler_end
|
||||||
_key_pressed_handler_backspace:
|
_key_pressed_handler_backspace:
|
||||||
debug_break
|
debug_break
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ if [ $? -eq 0 ]; then
|
||||||
/bin/bash ./load_mbr
|
/bin/bash ./load_mbr
|
||||||
cd ..
|
cd ..
|
||||||
printf "${green}Compiling Test Program...\n"
|
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}"
|
printf "\n${green}Running Application...\n\n${clear}"
|
||||||
./ddb config/testMachine.dvm --force-load newTest.bin 0x00 --verbose-load
|
./ddb config/testMachine.dvm --force-load newTest.bin 0x00 --verbose-load
|
||||||
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ if [ $? -eq 0 ]; then
|
||||||
/bin/bash ./load_mbr
|
/bin/bash ./load_mbr
|
||||||
cd ..
|
cd ..
|
||||||
printf "${green}Compiling Test Program...\n"
|
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}"
|
printf "\n${green}Running Application...\n\n${clear}"
|
||||||
./dvm config/testMachine.dvm --force-load newTest.bin 0x00
|
./dvm config/testMachine.dvm --force-load newTest.bin 0x00
|
||||||
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,5 @@ clear='\033[0m'
|
||||||
printf "${green}Reloading BIOS...\n${clear}"
|
printf "${green}Reloading BIOS...\n${clear}"
|
||||||
cd ..
|
cd ..
|
||||||
cp ../extra/dss/bios/* ./dss/bios/
|
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
|
cp dragon/bios.bin ../extra/dragon/bios.bin
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,8 @@ namespace dragon
|
||||||
}
|
}
|
||||||
else if (edit == "--extmov")
|
else if (edit == "--extmov")
|
||||||
args.cpu_extensions.push_back("extmov");
|
args.cpu_extensions.push_back("extmov");
|
||||||
|
else if (edit == "--extalu")
|
||||||
|
args.cpu_extensions.push_back("extalu");
|
||||||
else if (edit == "--verbose")
|
else if (edit == "--verbose")
|
||||||
args.verbose = true;
|
args.verbose = true;
|
||||||
else if (edit == "--save-exports")
|
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();
|
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 = "--extmov";
|
||||||
tmpCommand.addRightPadding(commandLength);
|
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 = "--help";
|
||||||
tmpCommand.addRightPadding(commandLength);
|
tmpCommand.addRightPadding(commandLength);
|
||||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Displays this help message.").reset().nl();
|
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();
|
opEdit.trim();
|
||||||
int16_t word = 0x0000;
|
int16_t word = 0x0000;
|
||||||
auto st = opEdit.tokenize(",");
|
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")
|
if (instEdit == "mov")
|
||||||
{
|
{
|
||||||
m_code.push_back(0x00);
|
m_code.push_back(0x00);
|
||||||
|
|
@ -1634,10 +1697,10 @@ namespace dragon
|
||||||
int16_t word2 = 0x0000;
|
int16_t word2 = 0x0000;
|
||||||
int16_t word3 = 0x0000;
|
int16_t word3 = 0x0000;
|
||||||
auto st = opEdit.tokenize(",");
|
auto st = opEdit.tokenize(",");
|
||||||
m_code.push_back(data::OpCodes::Ext01);
|
|
||||||
m_code.push_back(0x00);
|
|
||||||
if (instEdit == "omov")
|
if (instEdit == "omov")
|
||||||
{
|
{
|
||||||
|
m_code.push_back(data::OpCodes::Ext01);
|
||||||
|
m_code.push_back(0x00);
|
||||||
if (st.count() != 3)
|
if (st.count() != 3)
|
||||||
{
|
{
|
||||||
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
|
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
|
||||||
|
|
@ -1793,6 +1856,8 @@ namespace dragon
|
||||||
}
|
}
|
||||||
else if (instEdit == "omovb")
|
else if (instEdit == "omovb")
|
||||||
{
|
{
|
||||||
|
m_code.push_back(data::OpCodes::Ext01);
|
||||||
|
m_code.push_back(0x00);
|
||||||
if (st.count() != 3)
|
if (st.count() != 3)
|
||||||
{
|
{
|
||||||
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
|
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
|
||||||
|
|
@ -1946,6 +2011,8 @@ namespace dragon
|
||||||
}
|
}
|
||||||
else if (instEdit == "movo")
|
else if (instEdit == "movo")
|
||||||
{
|
{
|
||||||
|
m_code.push_back(data::OpCodes::Ext01);
|
||||||
|
m_code.push_back(0x00);
|
||||||
if (st.count() != 3)
|
if (st.count() != 3)
|
||||||
{
|
{
|
||||||
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
|
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
|
||||||
|
|
@ -2097,6 +2164,8 @@ namespace dragon
|
||||||
}
|
}
|
||||||
else if (instEdit == "movbo")
|
else if (instEdit == "movbo")
|
||||||
{
|
{
|
||||||
|
m_code.push_back(data::OpCodes::Ext01);
|
||||||
|
m_code.push_back(0x00);
|
||||||
if (st.count() != 3)
|
if (st.count() != 3)
|
||||||
{
|
{
|
||||||
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
|
std::cout << "Invalid operand number; " << line << "3 -> 3 required\n";
|
||||||
|
|
@ -2246,16 +2315,13 @@ namespace dragon
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
return;
|
||||||
{
|
|
||||||
std::cout << "Unknown instruction; " << line << " (" << instEdit << ")\n";
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (instEdit == "omov" || instEdit == "omovb" || instEdit == "movo" || instEdit == "movbo")
|
else if (instEdit == "omov" || instEdit == "omovb" || instEdit == "movo" || instEdit == "movbo")
|
||||||
{
|
{
|
||||||
std::cout << "ExtMov instruction detected, please add '--extmov' flag to dasm.\n";
|
std::cout << "ExtMov instruction detected, please add '--extmov' flag to dasm.\n";
|
||||||
exit(0);
|
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(), { (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)) });
|
m_disassembly.insert(m_disassembly.begin(), { m_loadAddress, ostd::String("jmp ").add(ostd::Utils::getHexStr(entryAddr, true, 2)) });
|
||||||
for (auto& d : m_symbolTable)
|
for (auto& d : m_symbolTable)
|
||||||
|
{
|
||||||
symbols.push_back(d.second);
|
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 (int32_t i = symbols.size() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
for (auto& dd : symbols[i].bytes)
|
for (int32_t j = 0; j < symbols[i].bytes.size(); j++)
|
||||||
newCode.push_back(dd);
|
newCode[symbols[i].address - m_loadAddress + j] = symbols[i].bytes[j];
|
||||||
}
|
}
|
||||||
for (auto& b : m_code)
|
for (auto& b : m_code)
|
||||||
newCode.push_back(b);
|
newCode.push_back(b);
|
||||||
|
|
|
||||||
|
|
@ -1038,10 +1038,13 @@ namespace dragon
|
||||||
auto& callStack = minfo.callStack;
|
auto& callStack = minfo.callStack;
|
||||||
int32_t level = -1;
|
int32_t level = -1;
|
||||||
ostd::String ch_ang_u = "";
|
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_l = "|";
|
||||||
ostd::String ch_ang_d = "";
|
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)
|
for (auto& call : callStack)
|
||||||
{
|
{
|
||||||
ostd::String call_info = call.info.new_trim().toLower();
|
ostd::String call_info = call.info.new_trim().toLower();
|
||||||
|
|
@ -1056,7 +1059,7 @@ namespace dragon
|
||||||
}
|
}
|
||||||
else if (call_info == "hw int")
|
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++;
|
level++;
|
||||||
}
|
}
|
||||||
else if (call_info == "ret")
|
else if (call_info == "ret")
|
||||||
|
|
@ -1095,7 +1098,11 @@ namespace dragon
|
||||||
rgx.fg("\\$\\w+", "Green"); //Labels
|
rgx.fg("\\$\\w+", "Green"); //Labels
|
||||||
|
|
||||||
out.fg(ostd::ConsoleColors::BrightGray).p("|").reset();
|
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.fg(ostd::ConsoleColors::BrightGray).p("| > ").reset();
|
||||||
out.pStyled(rgx).nl().reset();
|
out.pStyled(rgx).nl().reset();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ namespace dragon
|
||||||
drawCharacter((uint8_t*)screenPixels, screenWidth, screenHeight, (uint8_t*)fontPixels, x, y, c, color, background);
|
drawCharacter((uint8_t*)screenPixels, screenWidth, screenHeight, (uint8_t*)fontPixels, x, y, c, color, background);
|
||||||
x += FONT_CHAR_W;
|
x += FONT_CHAR_W;
|
||||||
}
|
}
|
||||||
|
s_cursor_pos_x = x;
|
||||||
|
if (s_cursor_pos_x >= CONSOLE_CHARS_H)
|
||||||
|
s_cursor_pos_x = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,7 @@ namespace dragon
|
||||||
inline static constexpr int32_t FONT_H_CHARS = 16;
|
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_H = 90;
|
||||||
inline static constexpr int32_t CONSOLE_CHARS_V = 21;
|
inline static constexpr int32_t CONSOLE_CHARS_V = 21;
|
||||||
|
|
||||||
|
inline static int8_t s_cursor_pos_x = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -464,6 +464,232 @@ namespace dragon
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -59,6 +59,38 @@ namespace dragon
|
||||||
uint8_t getInstructionSIze(uint8_t opCode) override;
|
uint8_t getInstructionSIze(uint8_t opCode) override;
|
||||||
bool execute(VirtualCPU& vcpu) 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;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,6 +174,7 @@ namespace dragon
|
||||||
interruptData.info = "HW INT";
|
interruptData.info = "HW INT";
|
||||||
interruptData.addr = intValue;
|
interruptData.addr = intValue;
|
||||||
interruptData.inst_addr = 0x0000;
|
interruptData.inst_addr = 0x0000;
|
||||||
|
interruptData.interrupts_disabled = !readFlag(data::Flags::InterruptsEnabled);
|
||||||
ostd::SignalHandler::emitSignal(DragonRuntime::SignalListener::Signal_HardwareInterruptOccurred, ostd::tSignalPriority::RealTime, interruptData);
|
ostd::SignalHandler::emitSignal(DragonRuntime::SignalListener::Signal_HardwareInterruptOccurred, ostd::tSignalPriority::RealTime, interruptData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace dragon
|
||||||
int16_t readRegister(uint8_t reg);
|
int16_t readRegister(uint8_t reg);
|
||||||
int16_t writeRegister16(uint8_t reg, int16_t value);
|
int16_t writeRegister16(uint8_t reg, int16_t value);
|
||||||
int8_t writeRegister8(uint8_t reg, int8_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);
|
int8_t fetch8(void);
|
||||||
int16_t fetch16(void);
|
int16_t fetch16(void);
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,22 @@ namespace dragon
|
||||||
void VirtualDisplay::onRender(void)
|
void VirtualDisplay::onRender(void)
|
||||||
{
|
{
|
||||||
auto& config = DragonRuntime::machine_config;
|
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)
|
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++)
|
for (int32_t i = 0; i < m_singleTextLines.size(); i++)
|
||||||
{
|
{
|
||||||
auto& line = m_singleTextLines[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;
|
m_refreshScreen = false;
|
||||||
}
|
}
|
||||||
|
|
@ -82,10 +91,16 @@ namespace dragon
|
||||||
void VirtualDisplay::single_text_add_char_to_line(char c)
|
void VirtualDisplay::single_text_add_char_to_line(char c)
|
||||||
{
|
{
|
||||||
auto& config = DragonRuntime::machine_config;
|
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)
|
if (m_singleTextLines.size() == 0)
|
||||||
{
|
{
|
||||||
m_singleTextLines.push_back(ostd::String().addChar(c));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
|
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
|
||||||
|
|
@ -97,12 +112,18 @@ namespace dragon
|
||||||
{
|
{
|
||||||
m_singleTextLines.push_back(ostd::String().addChar(c));
|
m_singleTextLines.push_back(ostd::String().addChar(c));
|
||||||
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
|
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
|
else
|
||||||
{
|
{
|
||||||
line.addChar(c);
|
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;
|
else return;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ namespace dragon
|
||||||
inline static constexpr uint8_t VideoMode = 0x00;
|
inline static constexpr uint8_t VideoMode = 0x00;
|
||||||
inline static constexpr uint8_t Signal = 0x03;
|
inline static constexpr uint8_t Signal = 0x03;
|
||||||
inline static constexpr uint8_t TextSingleCharacter = 0x04;
|
inline static constexpr uint8_t TextSingleCharacter = 0x04;
|
||||||
|
inline static constexpr uint8_t TextSingleInvertColors = 0x05;
|
||||||
};
|
};
|
||||||
public: struct tVideoModeValues
|
public: struct tVideoModeValues
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,10 @@ namespace dragon
|
||||||
{
|
{
|
||||||
config.cpuext_list[ext_nr++] = new hw::cpuext::ExtMov;
|
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
|
else continue; //TODO: Warning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +72,23 @@ namespace dragon
|
||||||
lineEdit = tokens.next();
|
lineEdit = tokens.next();
|
||||||
config.singleColor_background.set(lineEdit);
|
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
|
else continue; //TODO: Warning
|
||||||
}
|
}
|
||||||
return validate_machine_config(config);
|
return validate_machine_config(config);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ namespace dragon
|
||||||
{
|
{
|
||||||
std::map<int32_t, ostd::String> vdisk_paths;
|
std::map<int32_t, ostd::String> vdisk_paths;
|
||||||
std::map<int32_t, data::CPUExtension*> cpuext_list;
|
std::map<int32_t, data::CPUExtension*> cpuext_list;
|
||||||
|
int32_t clock_rate_sec { 500 };
|
||||||
|
bool fixed_clock { true };
|
||||||
ostd::String bios_path;
|
ostd::String bios_path;
|
||||||
ostd::String cmos_path;
|
ostd::String cmos_path;
|
||||||
ostd::Color singleColor_background;
|
ostd::Color singleColor_background;
|
||||||
|
|
|
||||||
|
|
@ -280,14 +280,8 @@ namespace dragon
|
||||||
}
|
}
|
||||||
memMap.mapDevice(ram, dragon::data::MemoryMapAddresses::Memory_Start, dragon::data::MemoryMapAddresses::Memory_End, false, "RAM");
|
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)
|
if (verbose)
|
||||||
{
|
|
||||||
out.fg(ostd::ConsoleColors::Magenta).p(" Initializing vCPU reset sequence:").nl();
|
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;
|
uint16_t reset_ip_addr = 0x0000;
|
||||||
if (verbose)
|
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();
|
out.nl().nl();
|
||||||
s_trackMachineInfo = trackMachineInfoDiff;
|
s_trackMachineInfo = trackMachineInfoDiff;
|
||||||
s_trackCallStack = trackCallStack;
|
s_trackCallStack = trackCallStack;
|
||||||
|
|
@ -327,10 +336,14 @@ namespace dragon
|
||||||
|
|
||||||
void DragonRuntime::runMachine(void)
|
void DragonRuntime::runMachine(void)
|
||||||
{
|
{
|
||||||
double clock_speed_us = 2000;
|
double clock_speed_us = 1000000.0 / machine_config.clock_rate_sec;
|
||||||
double acc = 0;
|
double acc = 0;
|
||||||
|
uint64_t avg_count = 0;
|
||||||
|
uint64_t _time = 0;
|
||||||
|
double avg_tot = 0;
|
||||||
ostd::Timer clock_timer;
|
ostd::Timer clock_timer;
|
||||||
bool running = true;
|
bool running = true;
|
||||||
|
bool fixed_clock = machine_config.fixed_clock;
|
||||||
while (running || vDiskInterface.isBusy())
|
while (running || vDiskInterface.isBusy())
|
||||||
{
|
{
|
||||||
clock_timer.startCount(ostd::eTimeUnits::Microseconds);
|
clock_timer.startCount(ostd::eTimeUnits::Microseconds);
|
||||||
|
|
@ -346,15 +359,17 @@ namespace dragon
|
||||||
processErrors();
|
processErrors();
|
||||||
break;
|
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)
|
if (acc == 500)
|
||||||
{
|
{
|
||||||
std::cout << _time << "\n";
|
avg_count++;
|
||||||
|
avg_tot += _time;
|
||||||
|
s_avgInstTime = (uint64_t)std::round(avg_tot / avg_count);
|
||||||
acc = 0;
|
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)
|
if (inst == data::OpCodes::CallImm)
|
||||||
{
|
{
|
||||||
uint16_t call_addr = memMap.read16(instAddr + 1);
|
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)
|
else if (inst == data::OpCodes::CallReg)
|
||||||
{
|
{
|
||||||
uint8_t reg_addr = memMap.read8(instAddr + 1);
|
uint8_t reg_addr = memMap.read8(instAddr + 1);
|
||||||
uint16_t call_addr = cpu.readRegister(reg_addr);
|
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)
|
else if (interrupts_enabled && inst == data::OpCodes::Int)
|
||||||
{
|
{
|
||||||
uint8_t int_num = memMap.read8(instAddr + 1);
|
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)
|
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)
|
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 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,11 @@ namespace dragon
|
||||||
public: struct tCallInfo : public ostd::BaseObject
|
public: struct tCallInfo : public ostd::BaseObject
|
||||||
{
|
{
|
||||||
inline tCallInfo(void) { }
|
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;
|
ostd::String info;
|
||||||
uint16_t addr;
|
uint16_t addr;
|
||||||
uint16_t inst_addr;
|
uint16_t inst_addr;
|
||||||
|
bool interrupts_disabled;
|
||||||
};
|
};
|
||||||
public: struct tCommandLineArgs
|
public: struct tCommandLineArgs
|
||||||
{
|
{
|
||||||
|
|
@ -101,6 +102,7 @@ namespace dragon
|
||||||
inline static const tMachineDebugInfo& getMachineInfoDiff(void) { return s_machineInfo; }
|
inline static const tMachineDebugInfo& getMachineInfoDiff(void) { return s_machineInfo; }
|
||||||
inline static bool hasError(void) { return data::ErrorHandler::hasError(); }
|
inline static bool hasError(void) { return data::ErrorHandler::hasError(); }
|
||||||
inline static ostd::ConsoleOutputHandler& output(void) { return out; }
|
inline static ostd::ConsoleOutputHandler& output(void) { return out; }
|
||||||
|
inline static uint64_t getAvgClockSpeed(void) { return (uint64_t)std::round(1000000.0 / s_avgInstTime); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void __get_machine_footprint(tMachineDebugInfo* machineInfo, std::vector<uint16_t> trackedAddresses, bool previous);
|
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 tMachineConfig machine_config;
|
||||||
|
|
||||||
|
inline static uint64_t s_avgInstTime { 0 };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static tMachineDebugInfo s_machineInfo;
|
inline static tMachineDebugInfo s_machineInfo;
|
||||||
inline static bool s_trackMachineInfo { false };
|
inline static bool s_trackMachineInfo { false };
|
||||||
inline static bool s_trackCallStack { false };
|
inline static bool s_trackCallStack { false };
|
||||||
inline static SignalListener s_signalListener;
|
inline static SignalListener s_signalListener;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline static const int32_t RETURN_VAL_CLOSE_DEBUGGER = 128;
|
inline static const int32_t RETURN_VAL_CLOSE_DEBUGGER = 128;
|
||||||
inline static const int32_t RETURN_VAL_CLOSE_RUNTIME = 256;
|
inline static const int32_t RETURN_VAL_CLOSE_RUNTIME = 256;
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,28 @@ namespace dragon
|
||||||
inline static constexpr uint8_t KeyPressed = 0xA0;
|
inline static constexpr uint8_t KeyPressed = 0xA0;
|
||||||
inline static constexpr uint8_t KeyReleased = 0xA1;
|
inline static constexpr uint8_t KeyReleased = 0xA1;
|
||||||
inline static constexpr uint8_t TextEntered = 0xA2;
|
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
|
class CPUExtension
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue