Compare commits
66 commits
Developmen
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| fd38874932 | |||
| 6d9016cdae | |||
| 051a404e42 | |||
| de279f4721 | |||
| 59d9d8f910 | |||
| 0fecd6f3d1 | |||
| c81d2dcfea | |||
| 4aa5e318f0 | |||
| 6f0bed74d2 | |||
| 3123ae6231 | |||
| d1362c0218 | |||
| 16b706175d | |||
| 2486e5e4c0 | |||
| d0e8f5d43d | |||
| 327d0dd108 | |||
| 119da0bb1e | |||
| 5d47b73298 | |||
| 4fcd89effd | |||
| af2ceb5e24 | |||
| b18c12b451 | |||
| 9a9de088c6 | |||
| 0ab126ad33 | |||
| 412b3601fc | |||
| 7f3530ea78 | |||
| 0e25847a69 | |||
| dcbf3cce66 | |||
| e3cb57e454 | |||
| 6ba7a1e098 | |||
| 8565debad1 | |||
| 702559e907 | |||
| 1206dddd53 | |||
| dc20f5cf39 | |||
| b90cc537ef | |||
| 69d9f49361 | |||
| bf4662e4b4 | |||
| 8d35484a20 | |||
| 2c7dbea53d | |||
| 9dd57c8057 | |||
| e5f1a62724 | |||
| 2f19ddc459 | |||
| e0059c8520 | |||
| 58c7d9e0b9 | |||
| bed680aeb2 | |||
| d1dfc42a50 | |||
| 8f92a19f28 | |||
| a9ba9c8013 | |||
| 2cbc8847b2 | |||
| c4de3e6d04 | |||
| 5e2ea9394a | |||
| 626b1b28e7 | |||
| b2bbf7c560 | |||
| 79261a67a2 | |||
| d8dee243a1 | |||
| f256b901a1 | |||
| f40ae0a036 | |||
| c9014b99b0 | |||
| 56e12f9949 | |||
| c851940762 | |||
| 522e31ec22 | |||
| 9fdd690d0c | |||
| 713711d247 | |||
| 085bdbc75c | |||
| cdd8afb05d | |||
| 42f25f4e0b | |||
| 758b1e41b8 | |||
| ddc3b9b0cd |
3
.clangd
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
CompileFlags:
|
||||
CompilationDatabase: bin
|
||||
|
||||
2
.gitignore
vendored
|
|
@ -1,4 +1,2 @@
|
|||
|
||||
bin
|
||||
tools/win-release-tools
|
||||
win-release
|
||||
31
.vscode/c_cpp_properties.json
vendored
|
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${default}",
|
||||
"${workspaceRoot}/../omnia-framework/src"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/clang++",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "linux-clang-x64"
|
||||
//"compileCommands": "${workspaceFolder}/compile_commands.json"
|
||||
},
|
||||
{
|
||||
"name": "Windows",
|
||||
"includePath": [
|
||||
"${default}",
|
||||
"${workspaceRoot}/../omnia-framework/src"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "C:\\msys64\\ucrt64\\bin\\clang++",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "windows-clang-x64"
|
||||
//"compileCommands": "${workspaceFolder}/compile_commands.json"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
143
.vscode/settings.json
vendored
|
|
@ -1,143 +0,0 @@
|
|||
{
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"files.associations": {
|
||||
"functional": "cpp",
|
||||
"thread": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"csetjmp": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"barrier": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"complex": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cuchar": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"source_location": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"latch": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"ranges": "cpp",
|
||||
"scoped_allocator": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"syncstream": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"*.rh": "cpp",
|
||||
"hash_set": "cpp",
|
||||
"strstream": "cpp",
|
||||
"expected": "cpp",
|
||||
"spanstream": "cpp",
|
||||
"stacktrace": "cpp",
|
||||
"*.ipp": "cpp",
|
||||
"format": "cpp",
|
||||
"stdfloat": "cpp"
|
||||
},
|
||||
|
||||
"workbench.colorCustomizations": {
|
||||
"editor.background": "#131313",
|
||||
"tab.hoverBackground": "#111",
|
||||
"tab.inactiveBackground": "#000",
|
||||
"tab.activeBackground": "#1b1b1b",
|
||||
"tab.activeBorder": "#bb5400",
|
||||
"editorIndentGuide.background": "#252525",
|
||||
"editorWhitespace.foreground": "#683700",
|
||||
"editor.lineHighlightBorder": "#1a1a1a",
|
||||
"editor.lineHighlightBackground": "#490050",
|
||||
"editorBracketMatch.background": "#444",
|
||||
"editorBracketMatch.border": "#b80318",
|
||||
"editor.selectionBackground": "#3b3b3b",
|
||||
"editor.selectionHighlightBackground": "#702900",
|
||||
"statusBar.background": "#2e2850",
|
||||
"minimap.background" : "#1b1b1b",
|
||||
"sideBar.background": "#1b1b1b"
|
||||
},
|
||||
|
||||
"workbench.editor.wrapTabs": true,
|
||||
"todohighlight.isEnable": true,
|
||||
"todohighlight.keywords": [
|
||||
{
|
||||
"text": "TODO:",
|
||||
"color": "red",
|
||||
"backgroundColor": "rgba(0, 0, 0, 0)"
|
||||
},
|
||||
{
|
||||
"text": "INFO:",
|
||||
"color": "blue",
|
||||
"backgroundColor": "rgba(0, 0, 0, 0)"
|
||||
},
|
||||
{
|
||||
"text": "HACK:",
|
||||
"color": "purple",
|
||||
"backgroundColor": "rgba(0, 0, 0, 0)"
|
||||
}
|
||||
],
|
||||
"editor.insertSpaces": false,
|
||||
|
||||
"workbench.list.openMode": "doubleClick"
|
||||
}
|
||||
180
CMakeLists.txt
|
|
@ -1,3 +1,10 @@
|
|||
#Variables
|
||||
#-----------------------------------------------------------------------------------------
|
||||
set(PROJ_NAME DragonVM)
|
||||
set(MAJOR_VER 0)
|
||||
set(MINOR_VER 4)
|
||||
#-----------------------------------------------------------------------------------------
|
||||
|
||||
#Setup
|
||||
#-----------------------------------------------------------------------------------------
|
||||
set(CMAKE_CXX_COMPILER "clang++")
|
||||
|
|
@ -5,177 +12,176 @@ set(CMAKE_C_COMPILER "clang")
|
|||
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)
|
||||
file(STRINGS "./tools/build.nr" BUILD_NUMBER)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
file(STRINGS "./other/build.nr" BUILD_NUMBER)
|
||||
#-----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#Variables
|
||||
#-----------------------------------------------------------------------------------------
|
||||
set(PROJ_NAME DragonVM)
|
||||
set(MAJOR_VER 0)
|
||||
set(MINOR_VER 1)
|
||||
|
||||
message("** Building ${PROJ_NAME} ${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}")
|
||||
#-----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(STATUS "Debug Configuration")
|
||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
message(STATUS "Release Configuration")
|
||||
endif()
|
||||
|
||||
#Sources
|
||||
#-----------------------------------------------------------------------------------------
|
||||
list(APPEND INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_LIST_DIR}/src
|
||||
${CMAKE_CURRENT_LIST_DIR}/../omnia-framework/src
|
||||
)
|
||||
list(APPEND RUNTIME_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/runtime_main.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/DragonRuntime.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/widgets/VirtualConsoleWidget.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/VirtualConsoleOutputHandler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/VirtualConsole.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/MemoryMapper.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualIODevices.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/LegacyOstdSerial.cpp
|
||||
)
|
||||
list(APPEND DEBUGGER_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/debugger/debugger_main.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/debugger/DisassemblyLoader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/debugger/Debugger.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/DebuggerWindow.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/widgets/VirtualConsoleWidget.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/VirtualConsoleOutputHandler.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/MemoryMapper.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualIODevices.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/DragonRuntime.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/assembler/Assembler.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/assembler/IncludePreprocessor.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/assembler/DASMApp.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/LegacyOstdSerial.cpp
|
||||
)
|
||||
list(APPEND ASSEMBLER_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/assembler/assembler_main.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/assembler/Assembler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/assembler/IncludePreprocessor.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/assembler/DASMApp.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/LegacyOstdSerial.cpp
|
||||
)
|
||||
list(APPEND TOOLS_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/tools_main.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/Tools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/LegacyOstdSerial.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/debugger/DisassemblyLoader.cpp
|
||||
)
|
||||
#-----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#Targets
|
||||
#-----------------------------------------------------------------------------------------
|
||||
set(RUNTIME_TARGET dvm)
|
||||
add_executable(${RUNTIME_TARGET} ${RUNTIME_SOURCE_FILES})
|
||||
if(WIN32)
|
||||
target_sources(${MAIN_EXECUTABLE} PUBLIC "${CMAKE_CURRENT_LIST_DIR}/other/dvm_appIcon.rc")
|
||||
endif()
|
||||
target_include_directories(${RUNTIME_TARGET} PUBLIC ${INCLUDE_DIRS})
|
||||
|
||||
|
||||
set(DEBUGGER_TARGET ddb)
|
||||
add_executable(${DEBUGGER_TARGET} ${DEBUGGER_SOURCE_FILES})
|
||||
if(WIN32)
|
||||
target_sources(${MAIN_EXECUTABLE} PUBLIC "${CMAKE_CURRENT_LIST_DIR}/other/ddb_appIcon.rc")
|
||||
endif()
|
||||
target_include_directories(${DEBUGGER_TARGET} PUBLIC ${INCLUDE_DIRS})
|
||||
|
||||
|
||||
set(ASSEMBLER_TARGET dasm)
|
||||
add_executable(${ASSEMBLER_TARGET} ${ASSEMBLER_SOURCE_FILES})
|
||||
if(WIN32)
|
||||
target_sources(${MAIN_EXECUTABLE} PUBLIC "${CMAKE_CURRENT_LIST_DIR}/other/dasm_appIcon.rc")
|
||||
endif()
|
||||
target_include_directories(${ASSEMBLER_TARGET} PUBLIC ${INCLUDE_DIRS})
|
||||
|
||||
|
||||
set(TOOLS_TARGET dtools)
|
||||
add_executable(${TOOLS_TARGET} ${TOOLS_SOURCE_FILES})
|
||||
if(WIN32)
|
||||
target_sources(${MAIN_EXECUTABLE} PUBLIC "${CMAKE_CURRENT_LIST_DIR}/other/dtools_appIcon.rc")
|
||||
endif()
|
||||
target_include_directories(${TOOLS_TARGET} PUBLIC ${INCLUDE_DIRS})
|
||||
|
||||
target_compile_definitions(${RUNTIME_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER} - Alpha")
|
||||
target_compile_definitions(${RUNTIME_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}")
|
||||
target_compile_definitions(${DEBUGGER_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}")
|
||||
target_compile_definitions(${ASSEMBLER_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}")
|
||||
target_compile_definitions(${TOOLS_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}")
|
||||
|
||||
#TODO: Different flags for Release/Debug
|
||||
add_compile_options(-O3 -m32 -MMD -MP -Wall -ggdb)
|
||||
if (UNIX)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'")
|
||||
#target_link_libraries(${RUNTIME_TARGET} X11 GL)
|
||||
target_link_libraries(${RUNTIME_TARGET} xcb xcb-randr)
|
||||
target_link_libraries(${ASSEMBLER_TARGET} xcb xcb-randr)
|
||||
target_link_libraries(${TOOLS_TARGET} xcb xcb-randr)
|
||||
target_link_libraries(${DEBUGGER_TARGET} xcb xcb-randr)
|
||||
endif (UNIX)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_compile_definitions(${RUNTIME_TARGET} PUBLIC BUILD_CONFIG_DEBUG)
|
||||
target_compile_definitions(${DEBUGGER_TARGET} PUBLIC BUILD_CONFIG_DEBUG)
|
||||
target_compile_definitions(${ASSEMBLER_TARGET} PUBLIC BUILD_CONFIG_DEBUG)
|
||||
target_compile_definitions(${TOOLS_TARGET} PUBLIC BUILD_CONFIG_DEBUG)
|
||||
add_compile_options(-O3 -MMD -MP -Wall -ggdb)
|
||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
target_compile_definitions(${RUNTIME_TARGET} PUBLIC BUILD_CONFIG_RELEASE)
|
||||
target_compile_definitions(${DEBUGGER_TARGET} PUBLIC BUILD_CONFIG_RELEASE)
|
||||
target_compile_definitions(${ASSEMBLER_TARGET} PUBLIC BUILD_CONFIG_RELEASE)
|
||||
target_compile_definitions(${TOOLS_TARGET} PUBLIC BUILD_CONFIG_RELEASE)
|
||||
add_compile_options(-MMD -MP -Wall)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set_target_properties(${RUNTIME_TARGET} PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
set_target_properties(${DEBUGGER_TARGET} PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
set_target_properties(${ASSEMBLER_TARGET} PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
set_target_properties(${TOOLS_TARGET} PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
endif()
|
||||
#-----------------------------------------------------------------------------------------
|
||||
|
||||
#Linking
|
||||
#-----------------------------------------------------------------------------------------
|
||||
if (WIN32)
|
||||
target_link_libraries(${RUNTIME_TARGET} mingw32)
|
||||
target_link_libraries(${ASSEMBLER_TARGET} mingw32)
|
||||
target_link_libraries(${TOOLS_TARGET} mingw32)
|
||||
target_link_libraries(${DEBUGGER_TARGET} mingw32)
|
||||
endif (WIN32)
|
||||
target_link_libraries(${RUNTIME_TARGET} SDL2main SDL2 SDL2_mixer SDL2_image)
|
||||
target_link_libraries(${DEBUGGER_TARGET} SDL2main SDL2 SDL2_mixer SDL2_image)
|
||||
|
||||
# target_link_libraries(${RUNTIME_TARGET} sfml-system sfml-window sfml-graphics)
|
||||
#-----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#Linking
|
||||
#-----------------------------------------------------------------------------------------
|
||||
find_library(OMNIA_STD_LIB
|
||||
NAMES ostd
|
||||
HINTS "${CMAKE_CURRENT_SOURCE_DIR}/../omnia-framework/bin/"
|
||||
NO_CACHE
|
||||
)
|
||||
target_link_libraries(${RUNTIME_TARGET} ${OMNIA_STD_LIB})
|
||||
target_link_libraries(${DEBUGGER_TARGET} ${OMNIA_STD_LIB})
|
||||
target_link_libraries(${ASSEMBLER_TARGET} ${OMNIA_STD_LIB})
|
||||
target_link_libraries(${TOOLS_TARGET} ${OMNIA_STD_LIB})
|
||||
#-----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#BuildNumber Target
|
||||
#-----------------------------------------------------------------------------------------
|
||||
if (WIN32)
|
||||
add_custom_command ( OUTPUT ./tools/build.nr
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/inc_bnr.exe
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tools/
|
||||
)
|
||||
endif (WIN32)
|
||||
if (UNIX)
|
||||
add_custom_command ( OUTPUT ./tools/build.nr
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/inc_bnr
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tools/
|
||||
)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,'$ORIGIN',-rpath,/usr/lib" )
|
||||
target_link_libraries(${RUNTIME_TARGET} xcb xcb-randr boost_regex)
|
||||
target_link_libraries(${ASSEMBLER_TARGET} xcb xcb-randr boost_regex)
|
||||
target_link_libraries(${TOOLS_TARGET} xcb xcb-randr boost_regex)
|
||||
target_link_libraries(${DEBUGGER_TARGET} xcb xcb-randr boost_regex)
|
||||
endif (UNIX)
|
||||
|
||||
add_custom_target(
|
||||
IncBnr ALL
|
||||
DEPENDS ./tools/build.nr
|
||||
)
|
||||
target_link_libraries(${RUNTIME_TARGET} SDL3 SDL3_image)
|
||||
target_link_libraries(${DEBUGGER_TARGET} SDL3 SDL3_image)
|
||||
|
||||
target_link_libraries(${RUNTIME_TARGET} ostd ogfx)
|
||||
target_link_libraries(${DEBUGGER_TARGET} ostd ogfx)
|
||||
target_link_libraries(${ASSEMBLER_TARGET} ostd)
|
||||
target_link_libraries(${TOOLS_TARGET} ostd)
|
||||
#-----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
add_custom_command(TARGET ${RUNTIME_TARGET} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/extra/ $<TARGET_FILE_DIR:${RUNTIME_TARGET}>
|
||||
VERBATIM
|
||||
)
|
||||
|
|
|
|||
674
LICENSE
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
21
README.md
|
|
@ -1,22 +1,3 @@
|
|||
# DragonVM
|
||||
|
||||
Compile instructions on Windows
|
||||
|
||||
**Step 1:**
|
||||
download MSYS2 from https://www.msys2.org/ and install it
|
||||
|
||||
**Step 2:**
|
||||
run MSYS2, and in the terminal run:
|
||||
```
|
||||
pacman -Syuu
|
||||
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-gdb mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-sfml mingw-w64-ucrt-x86_64-make mingw-w64-ucrt-x86_64-SDL2
|
||||
```
|
||||
|
||||
**Step 3:**
|
||||
open a UCRT64/MSYS2 command prompt inside the root directory of the project
|
||||
|
||||
**Step 4:**
|
||||
execute this command:
|
||||
```
|
||||
./compile
|
||||
```
|
||||
An amulator for a 16-bit machine that never existed
|
||||
|
|
|
|||
94
build
Executable file
|
|
@ -0,0 +1,94 @@
|
|||
#!/bin/bash
|
||||
|
||||
backtrack_changes() {
|
||||
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||
cp dragon/cmos.dr ../extra/dragon/cmos.dr
|
||||
cp dragon/bios.bin ../extra/dragon/bios.bin
|
||||
cp dss/sdk/bios_api.dss ../extra/dss/sdk/bios_api.dss
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
MAKE_COMMAND=make
|
||||
MAKEFILE_TYPE="Unix Makefiles"
|
||||
|
||||
if [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
|
||||
MAKE_COMMAND=mingw32-make.exe
|
||||
MAKEFILE_TYPE="MinGW Makefiles"
|
||||
fi
|
||||
|
||||
if [[ "$1" == "debug" || "$1" == "release" ]]; then
|
||||
BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
|
||||
rm -rf bin
|
||||
cmake -B bin -S ./ -G "$MAKEFILE_TYPE" -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$MAKE_COMMAND -C bin -j$(nproc) --no-print-directory
|
||||
cp -r extra/* bin/
|
||||
typeset -i build_number=$(cat other/build.nr)
|
||||
((build_number++))
|
||||
truncate -s 0 other/build.nr
|
||||
echo $build_number >> other/build.nr
|
||||
elif [[ "$1" == "windows_release" ]]; then
|
||||
cd other
|
||||
chmod +x build_windows_release.sh
|
||||
./build_windows_release.sh
|
||||
cd ../bin/DragonVM_w64
|
||||
./reload_env.sh
|
||||
cd ../..
|
||||
elif [[ "$1" == "linux_release" ]]; then
|
||||
cd other
|
||||
chmod +x build_linux_release.sh
|
||||
./build_linux_release.sh
|
||||
cd ../bin/DragonVM_linux64
|
||||
./reload_env.sh
|
||||
cd ../..
|
||||
elif [[ "$1" == "dependencies" ]]; then
|
||||
cd other
|
||||
chmod +x build_dependencies.sh
|
||||
./build_dependencies.sh
|
||||
cd ..
|
||||
else
|
||||
cp -r extra/* bin/
|
||||
printf "\n\033[0;32mBuilding Changes...\n\n\033[0m"
|
||||
$MAKE_COMMAND -C bin -j$(nproc) --no-print-directory
|
||||
mkdir -p bin/disassembly
|
||||
if [[ "$1" == "run" ]]; then
|
||||
printf "\n\033[0;32mRunning DragonVM runtime...\n\n\033[0m"
|
||||
cd bin
|
||||
./reload_env.sh
|
||||
./dvm config/testMachine.dvm
|
||||
backtrack_changes
|
||||
cd ..
|
||||
elif [[ "$1" == "dbg" ]]; then
|
||||
printf "\n\033[0;32mRunning DragonVM debug...\n\n\033[0m"
|
||||
cd bin
|
||||
./reload_env.sh -D
|
||||
./ddb config/testMachine.dvm --verbose-load
|
||||
backtrack_changes
|
||||
cd ..
|
||||
elif [[ "$1" == "dbgv" ]]; then
|
||||
printf "\n\033[0;32mRunning DragonVM debug...\n\n\033[0m"
|
||||
cd bin
|
||||
./reload_env.sh "-D --verbose-full"
|
||||
./ddb config/testMachine.dvm --verbose-load
|
||||
backtrack_changes
|
||||
cd ..
|
||||
elif [[ "$1" == "gdb" ]]; then
|
||||
printf "\n\033[0;32mDebugging Test Application...\n\n\033[0m"
|
||||
cd bin
|
||||
./reload_env.sh
|
||||
gdb -batch \
|
||||
-ex 'set pagination off' \
|
||||
-ex 'set print pretty on' \
|
||||
-ex 'set logging file gdb-last.log' \
|
||||
-ex 'set logging overwrite on' \
|
||||
-ex 'set logging on' \
|
||||
-ex 'handle SIGPIPE nostop noprint pass' \
|
||||
-ex run \
|
||||
-ex 'bt full' \
|
||||
-ex 'info locals' \
|
||||
-ex 'info args' \
|
||||
-ex quit \
|
||||
--args ./dvm config/testMachine.dvm
|
||||
cd ..
|
||||
fi
|
||||
fi
|
||||
16
compile
|
|
@ -1,16 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
rm -r bin
|
||||
|
||||
if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
|
||||
cmake -B bin -S ./
|
||||
cd bin
|
||||
make
|
||||
cd ..
|
||||
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
|
||||
cmake -B bin -S ./ -G "MinGW Makefiles"
|
||||
cd bin
|
||||
mingw32-make.exe
|
||||
cd ..
|
||||
cp ../omnia-framework/bin/libostd.dll ./bin
|
||||
fi
|
||||
|
|
@ -1,3 +1,14 @@
|
|||
Disks = dragon/disk1.dr
|
||||
Bios = dragon/bios.bin
|
||||
CMOS = dragon/cmos.dr
|
||||
CMOS = dragon/cmos.dr
|
||||
|
||||
cpuext = extmov, extalu
|
||||
fixed_clock = true
|
||||
clock_rate_sec = 5000
|
||||
memory_extension_pages = 16
|
||||
|
||||
screen_redraw_rate_per_second = 30
|
||||
|
||||
SingleColor_foreground = #009900FF
|
||||
SingleColor_background = #111111FF
|
||||
16Color_Palette = 0
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
0x0000
|
||||
BIOS (1024 Bytes)
|
||||
0x03FF
|
||||
-------
|
||||
0x0400
|
||||
CMOS (128 Bytes)
|
||||
BootDisk: 0x0010
|
||||
0x047F
|
||||
-------
|
||||
0x0480
|
||||
INTERRUPT VECTOR (512 Bytes)
|
||||
0x067F
|
||||
-------
|
||||
0x0680
|
||||
KEYBOARD MAPPING (224 Bytes)
|
||||
0x075F
|
||||
-------
|
||||
0x0760
|
||||
MOUSE MAPPING (32 Bytes)
|
||||
0x077F
|
||||
-------
|
||||
0x0780
|
||||
BIOS VIDEO MEMORY (3840 Bytes)
|
||||
0x000: Clear Color (1 Byte)
|
||||
0x001: Palette (1 Byte)
|
||||
0x002: UseTransparencyOn0x5 (1 Byte)
|
||||
0x003: Signal (1 Byte)
|
||||
0x00: Continue
|
||||
0x01: Clear Screen
|
||||
0x03C - 0xEFF: 3780 Bytes
|
||||
Structure:
|
||||
90x21 characters
|
||||
1 Byte ascii
|
||||
1 byte: 4 Bits background/4 bits foreground
|
||||
0x167F
|
||||
-------
|
||||
0x1680
|
||||
BOOTLOADER (512 Bytes)
|
||||
0x187F
|
||||
-------
|
||||
0x1880
|
||||
DISK INTERFACE (128 Bytes)
|
||||
Read/Write:
|
||||
Signal: 1 Byte
|
||||
0x00: Start Operation
|
||||
0x01: Cancel Current Operation
|
||||
0xFF: Ignore
|
||||
Mode: 1 Byte
|
||||
0x00: Read
|
||||
0x01: Write
|
||||
Disk: 1 Byte
|
||||
Sector: 2 Bytes
|
||||
Address: 2 Bytes
|
||||
DataSize: 2 Bytes
|
||||
DataAddress: 2 Byte
|
||||
ReadOnly:
|
||||
Status: 1 Byte
|
||||
0x00: Free
|
||||
0x01: Writing
|
||||
0x02: Reading
|
||||
CurrentDisk: 1 Byte
|
||||
CurrentSector: 2 Bytes
|
||||
CurrentAddress: 2 Bytes
|
||||
RestDataSize: 2 Bytes
|
||||
SourceData: 2 Bytes
|
||||
Free: 107 Byte
|
||||
0x18FF
|
||||
-------
|
||||
0x1900
|
||||
VIDEO CARD INTERFACE (256 Bytes)
|
||||
0x19FF
|
||||
-------
|
||||
0x1A00
|
||||
GENERIC SERIAL INTERFACE (64 Bytes)
|
||||
0x1A3F
|
||||
-------
|
||||
0x1A40
|
||||
RAM (58815 Bytes)
|
||||
0xFFFF
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
Software Interrupts:
|
||||
====================
|
||||
0x20: BIOS Interrupt (Uses R10 register for specific functionality)
|
||||
0x00: Set Interrupt Handler
|
||||
0x01: Clear Interrupt Handler
|
||||
0x10: Disk Interface
|
||||
0x30: BIOS Video Interrupt (Uses R10 register for specific functionality)
|
||||
0x00: Clear Screen
|
||||
|
||||
|
||||
Hardware Interrupts:
|
||||
====================
|
||||
0x80: Disk Interface Finished
|
||||
0x81: BiosVideo Screen Refreshed
|
||||
|
||||
|
||||
|
||||
|
||||
Default Palette BIOS Colors:
|
||||
====================
|
||||
0x0: Black
|
||||
0, 0, 0
|
||||
#000000
|
||||
0x1: Gray
|
||||
157, 157, 157
|
||||
#9D9D9D
|
||||
0x2: White
|
||||
255, 255, 255
|
||||
#FFFFFF
|
||||
0x3: Red
|
||||
190, 38, 51
|
||||
#BE2633
|
||||
0x4: Pimk
|
||||
224, 111, 139
|
||||
#E06F8B
|
||||
OLD -- 0x5: DarkBrown
|
||||
OLD -- 73, 60, 43
|
||||
OLD -- #493C2B
|
||||
0x5: Transparent
|
||||
--
|
||||
0x6: Brown
|
||||
164, 100, 34
|
||||
#A46422
|
||||
0x7: Orange
|
||||
235, 137, 49
|
||||
#EB8931
|
||||
0x8: Yellow
|
||||
247, 226, 107
|
||||
#F7E26B
|
||||
0x9: Dark Green
|
||||
47, 80, 42
|
||||
#2F502A
|
||||
0xA: Green
|
||||
68, 137, 26
|
||||
#44891A
|
||||
0xB: Slime Green
|
||||
163, 206, 39
|
||||
#A3CE27
|
||||
0xC: Night Blue
|
||||
27, 38, 50
|
||||
#1B2632
|
||||
0xD: Sea Blue
|
||||
0, 87, 132
|
||||
#005784
|
||||
0xE: Sky Blue
|
||||
49, 162, 242
|
||||
#31A2F2
|
||||
0xF: Cloud Blue
|
||||
178, 220, 239
|
||||
#B2DCEF
|
||||
|
Before Width: | Height: | Size: 122 KiB |
|
|
@ -1,10 +0,0 @@
|
|||
Regex: Javascript
|
||||
|
||||
Number Constants
|
||||
0x[0-9A-Fa-f]+|0b[0-1]+|(?<!\w)[0-9]+(?!\w)
|
||||
|
||||
Labels
|
||||
\$\w+
|
||||
|
||||
Registers (case-insensitive)
|
||||
(?<!\w)(r[1-9]|r10|fl|pp|rv|fp|sp|ip|acc)(?!\w)
|
||||
71
extra/dss/DragonOS/drivers/display_driver.dss
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
@guard _DISPLAY_DRIVER_DSS_
|
||||
|
||||
@include <../../sdk/palette.dss>
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
.data
|
||||
$textCell <Text16VModeCell>
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
.code
|
||||
|
||||
## =========================================================================================================================
|
||||
_init_display_driver:
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_print_string: ## _print_string(string* str)
|
||||
arg R1 ## @Param: str
|
||||
movb [$textCell.CoordX], 0
|
||||
movb [$textCell.CoordY], 0
|
||||
movb [$textCell.Foreground], DefaultPalette.Blue
|
||||
movb [$textCell.Background], DefaultPalette.Black
|
||||
mov R10, 0x22
|
||||
mov R8, R1
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_print_char: ## _print_char(int16 char, int16 x, int16 y, int16 color)
|
||||
arg R1 ## @Param: char
|
||||
arg R2 ## @Param: x
|
||||
arg R3 ## @Param: y
|
||||
arg R4 ## @Param: color
|
||||
movb [$textCell.CoordX], R2
|
||||
movb [$textCell.CoordY], R3
|
||||
movb [$textCell.Foreground], R4
|
||||
movb [$textCell.Background], DefaultPalette.Black
|
||||
movb [$textCell.Character], R1
|
||||
mov R10, 0x21
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_clear_screen: ## _clear_screen(int8_t color)
|
||||
arg R1
|
||||
movb [$textCell.Foreground], R1
|
||||
movb [$textCell.Background], R1
|
||||
movb [$textCell.Character], 0x20
|
||||
mov R10, 0x24
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
13
extra/dss/DragonOS/drivers/keyboard_driver.dss
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
@guard _KEYBOARD_DRIVER_DSS_
|
||||
|
||||
@include <../../sdk/ascii.dss>
|
||||
@include <../../sdk/keycodes.dss>
|
||||
|
||||
.code
|
||||
|
||||
_init_keyboard_driver: ## _init_keyboard_driver(func_ptr* key_pressed_handler)
|
||||
arg R9 ## @Param: key_pressed_handler
|
||||
mov R10, 0x00 ## int 0x20 param for set_interrupt_handler
|
||||
mov R8, 0xA0 ## 0xA0 is the hardware interrupt for KeyPressed
|
||||
int 0x20
|
||||
ret
|
||||
105
extra/dss/DragonOS/kernel0/kernel0.dss
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
.load 0x2C00
|
||||
.fixed 1024, 0xFF
|
||||
.entry _kernel0_main
|
||||
.header KERNEL0_BOOT
|
||||
|
||||
@include <../drivers/display_driver.dss>
|
||||
@include <../drivers/keyboard_driver.dss>
|
||||
@include <sdk/bios_api.dss>
|
||||
@include <memory.dss>
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
.data
|
||||
$test_str "Hello DragonOS! :)"
|
||||
$cursor_x:1
|
||||
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
.code
|
||||
_kernel0_main:
|
||||
push DefaultPalette.Black
|
||||
push 1
|
||||
call $_clear_screen
|
||||
push $test_str
|
||||
push 1
|
||||
call $_print_string
|
||||
debug_break
|
||||
_infinite_loop_0:
|
||||
## jmp $_infinite_loop_0
|
||||
|
||||
mov [$cursor_x], 0
|
||||
|
||||
## Init Memory Handler
|
||||
push 0
|
||||
call $_init_memory_handler
|
||||
|
||||
## Init Display driver
|
||||
push 0
|
||||
call $_init_display_driver
|
||||
|
||||
## Init Keyboard driver
|
||||
push $_key_pressed ## KeyPressed handler address passed to the _init_keyboard subroutine
|
||||
push 1
|
||||
call $_init_keyboard_driver
|
||||
|
||||
_infinite_loop:
|
||||
jmp $_infinite_loop
|
||||
|
||||
hlt
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_key_pressed:
|
||||
debug_break
|
||||
mov R1, [Keyboard_Registers.KEYCODE]
|
||||
|
||||
mov ACC, KeyCodes.Return
|
||||
jeq $_key_pressed_enter, R1
|
||||
|
||||
push R1
|
||||
push 1
|
||||
call $_is_char_printable
|
||||
|
||||
mov ACC, RV
|
||||
jne $_key_pressed_end, 1
|
||||
push R1
|
||||
mov R2, [$cursor_x]
|
||||
push R2
|
||||
push 1
|
||||
push DefaultPalette.Red
|
||||
push 4
|
||||
call $_print_char
|
||||
inc R2
|
||||
mov [$cursor_x], R2
|
||||
jmp $_key_pressed_end
|
||||
|
||||
_key_pressed_enter:
|
||||
mov [$cursor_x], 0
|
||||
mov R10, 0x25
|
||||
int 0x30
|
||||
jmp $_key_pressed_end
|
||||
|
||||
_key_pressed_end:
|
||||
ret
|
||||
|
||||
|
||||
_is_char_printable:
|
||||
arg R9
|
||||
mov ACC, KeyCodes.Spacebar
|
||||
jls $_is_char_printable_false, R9
|
||||
mov ACC, KeyCodes.LowerCase_z
|
||||
jgr $_is_char_printable_false, R9
|
||||
mov RV, 1
|
||||
ret
|
||||
_is_char_printable_false:
|
||||
mov RV, 0
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
15
extra/dss/DragonOS/kernel0/memory.dss
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
@guard _MEMORY_DSS_
|
||||
|
||||
@define _REG_OFFSET 0x09
|
||||
@define _REG_S1 0x07
|
||||
@define _REG_S2 0x08
|
||||
|
||||
@define _USABLE_MEM_START 0x353F
|
||||
@define _USABLE_MEM_SIZE 0xBAC0
|
||||
@define _MEM_TABLE_ADDR 0x30FF
|
||||
|
||||
.code
|
||||
|
||||
_init_memory_handler:
|
||||
nop
|
||||
ret
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
## ============================= Memory Mapped Devices and Registers =============================
|
||||
@define MBR_START_ADDRESS 0x1680
|
||||
@define INT_VEC_START_ADDRESS 0x0480
|
||||
@define DISK_INTERFACE_START_ADDRESS 0x1880
|
||||
@define MEMORY_START_ADDRESS 0x1A40
|
||||
@define CMOS_START_ADDRESS 0x0400
|
||||
@define BIOS_VIDEO_START_ADDRESS 0x0780
|
||||
@define BIOS_VIDEO_MEMORY_START_ADDRESS 0x07BC
|
||||
@define BIOS_VIDEO_MEMORY_END_ADDRESS 0x167F
|
||||
|
||||
@define _BIOS_VIDEO_REG_CLEAR_COLOR {BIOS_VIDEO_START_ADDRESS + 0x0000}
|
||||
@define _BIOS_VIDEO_REG_SIGNAL {BIOS_VIDEO_START_ADDRESS + 0x0003}
|
||||
## ===============================================================================================
|
||||
|
||||
@define _CMOS_REG_BOOT_DISK {CMOS_START_ADDRESS + 0x0010}
|
||||
|
||||
.load 0x0000 ## BIOS is mapped to address 0x0000 in memory
|
||||
.data
|
||||
$bios_version_number 0x00, 0x01 ## BIOS Version stored in memory
|
||||
|
||||
## ============================= BIOS Program =============================
|
||||
.code
|
||||
mov FL, 0b0000000000000001 ## Zero the FL Register and enable interrupts
|
||||
movb [{INT_VEC_START_ADDRESS + (0x20 * 3)}], 0xFF ## Setting up int 0x20 handler
|
||||
mov [{INT_VEC_START_ADDRESS + (0x20 * 3) + 1}], $_int_20_handler ## --
|
||||
|
||||
mov R10, 0x00 ## Setting up int 0x30 handler by using int 0x20 functionality
|
||||
mov R9, $_int_30_handler ## -Passing the handler's address
|
||||
mov R8, 0x30 ## -Passing the interrupt's code to setup
|
||||
int 0x20 ## -Calling int 0x20 with 0x00 as parameter, to set new handler up
|
||||
|
||||
## TODO: Probably move this code before interrupts are enabled
|
||||
## to prevent an interrupt being fired while loading MBR
|
||||
## data from disk
|
||||
## ----
|
||||
## MBR Loading
|
||||
push 0
|
||||
call $_load_mbr_data_block
|
||||
## ----
|
||||
|
||||
jmp MBR_START_ADDRESS ## Jump to start of MBR in memory
|
||||
hlt ## Just in case somehow execution reaches this point
|
||||
## ========================================================================
|
||||
|
||||
|
||||
|
||||
## ============================= BIOS Interrupt handler =============================
|
||||
_int_20_handler:
|
||||
mov ACC, R10
|
||||
jeq $_int_20_disk_interface, 0x0010
|
||||
jeq $_int_20_set_new_interrupt_handler, 0x0000
|
||||
jeq $_int_20_clear_interrupt, 0x0001
|
||||
jmp $_int_20_end
|
||||
_int_20_disk_interface:
|
||||
movb [{DISK_INTERFACE_START_ADDRESS + 0x1}], *R9 ## Mode
|
||||
inc R9
|
||||
movb [{DISK_INTERFACE_START_ADDRESS + 0x2}], *R9 ## Disk
|
||||
inc R9
|
||||
mov [{DISK_INTERFACE_START_ADDRESS + 0x3}], *R9 ## Sector
|
||||
inc R9
|
||||
inc R9
|
||||
mov [{DISK_INTERFACE_START_ADDRESS + 0x5}], *R9 ## Address
|
||||
inc R9
|
||||
inc R9
|
||||
mov [{DISK_INTERFACE_START_ADDRESS + 0x7}], *R9 ## Size
|
||||
inc R9
|
||||
inc R9
|
||||
mov [{DISK_INTERFACE_START_ADDRESS + 0x9}], *R9 ## Memory Address
|
||||
movb [DISK_INTERFACE_START_ADDRESS], 0x00 ## Signal set to "Start Operation"
|
||||
jmp $_int_20_end
|
||||
_int_20_set_new_interrupt_handler:
|
||||
push R8 ## Interrupt Code
|
||||
push R9 ## Handler Address
|
||||
push 2
|
||||
call $_set_interrupt_vector_entry
|
||||
jmp $_int_20_end
|
||||
_int_20_clear_interrupt:
|
||||
push R9
|
||||
push 0x0000
|
||||
push 2
|
||||
call $_set_interrupt_vector_entry
|
||||
_int_20_end:
|
||||
rti
|
||||
## ==================================================================================
|
||||
|
||||
## ========================== BIOS Video Interrupt handler =========================
|
||||
_int_30_handler:
|
||||
mov ACC, R10
|
||||
jeq $_int_30_clear_screen, 0x0000
|
||||
jmp $_int_30_end
|
||||
_int_30_clear_screen:
|
||||
movb [_BIOS_VIDEO_REG_SIGNAL], 0x01 ## Signal = ClearScreen
|
||||
_int_30_end:
|
||||
rti
|
||||
## ==================================================================================
|
||||
|
||||
|
||||
_load_mbr_data_block:
|
||||
movb [{DISK_INTERFACE_START_ADDRESS + 0x1}], 0x00 ## Mode = Read
|
||||
movb R1, [_CMOS_REG_BOOT_DISK]
|
||||
movb [{DISK_INTERFACE_START_ADDRESS + 0x2}], R1 ## Disk = Default
|
||||
mov [{DISK_INTERFACE_START_ADDRESS + 0x3}],0x0000 ## Sector = 0x0000
|
||||
mov [{DISK_INTERFACE_START_ADDRESS + 0x5}],0x0000 ## Address = 0x0000 (Start of Disk)
|
||||
##//TODO: currently set to 20 instead of 512, for debugging purposes
|
||||
mov [{DISK_INTERFACE_START_ADDRESS + 0x7}], 20 ## Size = 512 (Size of MBR is 512 bytes)
|
||||
mov [{DISK_INTERFACE_START_ADDRESS + 0x9}], MBR_START_ADDRESS ## MemoryAddress = MBR Address in memory
|
||||
movb [DISK_INTERFACE_START_ADDRESS], 0x00 ## Signal = Start
|
||||
_load_mbr_data_block_wait_loop:
|
||||
mov ACC, [{DISK_INTERFACE_START_ADDRESS + 0xB}] ## Moving <Status> register into ACC
|
||||
jne $_load_mbr_data_block_wait_loop, 0x00 ## If <Status> register not Free, loop around and wait
|
||||
ret
|
||||
|
||||
_calc_interrupt_vector_address:
|
||||
mov R1, *PP
|
||||
mul R1, 0x03 ## Multiply the interrupt code by 3 for memory alignment
|
||||
mov R1, ACC
|
||||
add R1, INT_VEC_START_ADDRESS ## Add Interrupt Vector base address to Interrupt code
|
||||
mov RV, ACC
|
||||
ret
|
||||
|
||||
_set_interrupt_vector_entry:
|
||||
mov R1, *PP
|
||||
push R1
|
||||
push 1
|
||||
call $_calc_interrupt_vector_address
|
||||
mov R1, RV
|
||||
dec PP
|
||||
dec PP
|
||||
mov ACC, *PP
|
||||
jeq $_set_interrupt_vector_entry_disable, 0x0000
|
||||
movb *R1, 0xFF
|
||||
jmp $_set_interrupt_vector_entry_end
|
||||
_set_interrupt_vector_entry_disable:
|
||||
movb *R1, 0x00
|
||||
_set_interrupt_vector_entry_end:
|
||||
inc R1
|
||||
mov *R1, ACC
|
||||
ret
|
||||
|
||||
.fixed 1024, 0x00 ## BIOS Needs to be 1024 Bytes exactly
|
||||
349
extra/dss/bios/data.dss
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
@guard _DATA_DSS_
|
||||
|
||||
@export BIOS_API dss/sdk/bios_api.dss
|
||||
|
||||
@export_comment BIOS_API " --"
|
||||
@export_comment BIOS_API " -- This file is automatically generated by the DragonAssembler (version %dasm_version%) "
|
||||
@export_comment BIOS_API " -- Please do not modify this file in any way. "
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
## ============================= Memory Mapped Devices and Registers =============================
|
||||
@export_comment BIOS_API " These are the base addresses of the memory map."
|
||||
@raw_export_start BIOS_API
|
||||
@group MemoryAddresses
|
||||
MBR 0x1380
|
||||
INT_VEC 0x1080
|
||||
DISK_INTERFACE 0x1580
|
||||
RAM 0x1740
|
||||
CMOS 0x1000
|
||||
VGA 0x1600
|
||||
KEYBOARD 0x1280
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
@export_comment BIOS_API " These are the addresses of CMOS data."
|
||||
@raw_export_start BIOS_API
|
||||
@group CMOS_Settings
|
||||
MEM_START { MemoryAddresses.CMOS + 0x0000 }
|
||||
MEM_SIZE { MemoryAddresses.CMOS + 0x0002 }
|
||||
CLOCK_SPEED { MemoryAddresses.CMOS + 0x0004 }
|
||||
SCREEN_REDRAW_RATE { MemoryAddresses.CMOS + 0x0006 }
|
||||
SCREEN_WIDTH { MemoryAddresses.CMOS + 0x0007 }
|
||||
SCREEN_HEIGHT { MemoryAddresses.CMOS + 0x0009 }
|
||||
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
|
||||
STACK_SIZE { MemoryAddresses.CMOS + 0x0011 }
|
||||
|
||||
DISK_LIST { MemoryAddresses.CMOS + 0x007E }
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
@export_comment BIOS_API " These are the FLAG addresses."
|
||||
@raw_export_start BIOS_API
|
||||
@group Flags
|
||||
InterruptsEnabled 0x00
|
||||
OffsetModeEnabled 0x01
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
|
||||
@export_comment BIOS_API " These are the Hardware Interrupt codes of this machine."
|
||||
@raw_export_start BIOS_API
|
||||
@group HW_Int
|
||||
DISK_INTERFACE_FINISHED 0x80
|
||||
KEY_PRESSED 0xA0
|
||||
KEY_RELEASED 0xA1
|
||||
TEXT_ENTERED 0xA2
|
||||
|
||||
TEXT16_SCREEN_REFRESHED 0xE0
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
|
||||
@export_comment BIOS_API " These are the memory-mapped registers used to interact with the video card's interface."
|
||||
@raw_export_start BIOS_API
|
||||
@group VGA_Registers
|
||||
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
|
||||
CLEAR_COLOR { MemoryAddresses.VGA + 0x0001 }
|
||||
PALETTE { MemoryAddresses.VGA + 0x0002 }
|
||||
SIGNAL { MemoryAddresses.VGA + 0x0003 }
|
||||
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
|
||||
TEXT_SIGNLE_INVERT { MemoryAddresses.VGA + 0x0005 }
|
||||
TEXT_SIGNLE_STR { MemoryAddresses.VGA + 0x0006 }
|
||||
|
||||
FLAGS { MemoryAddresses.VGA + 0x007E }
|
||||
|
||||
MEMORY_CONTROLLER_X { MemoryAddresses.VGA + 0x0080 }
|
||||
MEMORY_CONTROLLER_X_BYTE { MemoryAddresses.VGA + 0x0080 + 1 }
|
||||
MEMORY_CONTROLLER_Y { MemoryAddresses.VGA + 0x0082 }
|
||||
MEMORY_CONTROLLER_Y_BYTE { MemoryAddresses.VGA + 0x0082 + 1 }
|
||||
MEMORY_CONTROLLER_CHAR { MemoryAddresses.VGA + 0x0084 }
|
||||
MEMORY_CONTROLLER_BG_COL { MemoryAddresses.VGA + 0x0085 }
|
||||
MEMORY_CONTROLLER_FG_COL { MemoryAddresses.VGA + 0x0086 }
|
||||
|
||||
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
|
||||
@export_comment BIOS_API " These are the memory-mapped registers used to interact with the keyboard's interface."
|
||||
@raw_export_start BIOS_API
|
||||
@group Keyboard_Registers
|
||||
MODIFIERS_BITFIELD { MemoryAddresses.KEYBOARD + 0x0000 }
|
||||
KEYCODE { MemoryAddresses.KEYBOARD + 0x0002 }
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
|
||||
@export_comment BIOS_API " These are the different Video Modes that the video card supports."
|
||||
@raw_export_start BIOS_API
|
||||
@group VGA_VideoModes
|
||||
TEXT_SINGLE_COLOR 0x00
|
||||
TEXT_16_COLORS 0x01
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
|
||||
@export_comment BIOS_API " These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode."
|
||||
@raw_export_start BIOS_API
|
||||
@group Sig_VGA_Text_Single_Color
|
||||
CONTINUE 0x00
|
||||
PRINT_CHAR 0x02
|
||||
STORE_CHAR 0x03
|
||||
PRINT_FLUSH_BUFF 0x04
|
||||
FLUSH_BUFF 0x05
|
||||
PRINT_BUFF 0x06
|
||||
PRINT_STRING 0x07
|
||||
|
||||
REFRESH_SCREEN 0xE0
|
||||
CLEAR_SCREEN 0xE1
|
||||
REDRAW_SCREEN 0xE2
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
|
||||
@export_comment BIOS_API " These are signals used to comunicate with the video card's interface, when in TEXT16_COLOR mode."
|
||||
@raw_export_start BIOS_API
|
||||
@group Sig_VGA_Text_16_Color
|
||||
CONTINUE 0x00
|
||||
|
||||
SWAP_BUFFERS 0x10
|
||||
WRITE_VRAM 0x11
|
||||
SCROLL 0x12
|
||||
|
||||
FORCE_REFRESH_SCREEN 0xE0
|
||||
FORCE_CLEAR_SCREEN 0xE1
|
||||
FORCE_REDRAW_SCREEN 0xE2
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
|
||||
@define S_REG_1 0x07
|
||||
@define S_REG_2 0x08
|
||||
@define S_REG_OFFSET 0x09
|
||||
|
||||
@define INST_BIOS_NODE_TOGGLE 0x02
|
||||
## ===============================================================================================
|
||||
|
||||
|
||||
|
||||
## ========================================== Other Data =========================================
|
||||
@export_comment BIOS_API " Structure of a DPT (Dragon Partition Table)."
|
||||
@raw_export_start BIOS_API
|
||||
@group DPTStructure
|
||||
DISK_ADDR 0x0200
|
||||
ENTRIES_START 0x000C
|
||||
|
||||
ENTRY_START_ADDR 0x0000
|
||||
ENTRY_PART_SIZE 0x0004
|
||||
ENTRY_FLAGS 0x0008
|
||||
ENTRY_PART_LBL 0x0024
|
||||
|
||||
ID_CODE 0xF1CA
|
||||
ENTRY_SIZE_B 100
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
@export_comment BIOS_API " Structure of a Bootable partitions (Dragon Partition Table)."
|
||||
@raw_export_start BIOS_API
|
||||
@group DPTBootPartStructure
|
||||
ID_ADDR 0x0000
|
||||
CODE_START 0x0020
|
||||
|
||||
ID_CODE 0xF1C4
|
||||
CODE_SIZE_B 1024
|
||||
HEADER_SIZE_B 32
|
||||
CODE_LOAD_ADDR 0x2C00
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
@export_comment BIOS_API " Structure to store a DPT block."
|
||||
@raw_export_start BIOS_API
|
||||
@struct DPTBlock
|
||||
ID:2
|
||||
VersionMaj:1
|
||||
VersionMin:1
|
||||
PartCount:1
|
||||
Reserved:7
|
||||
Entries:500
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
@export_comment BIOS_API " Structure to store a DPT Partition block."
|
||||
@raw_export_start BIOS_API
|
||||
@struct DPTPartitionBlock
|
||||
StartAddress:4
|
||||
Size:4
|
||||
Flags:2
|
||||
Reserved:26
|
||||
Label:64
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
@export_comment BIOS_API " Structure to store a character cell for the Text16-Video-Mode."
|
||||
@raw_export_start BIOS_API
|
||||
@struct Text16VModeCell
|
||||
Character:1
|
||||
Foreground:1
|
||||
Background:1
|
||||
CoordX:1
|
||||
CoordY:1
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
@export_comment BIOS_API " Debugger Profiler time units."
|
||||
@raw_export_start BIOS_API
|
||||
@group DBGProfilerTime
|
||||
MILLIS 0x00
|
||||
SECS 0x01
|
||||
MICROS 0x02
|
||||
NANOS 0x03
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
@export_comment BIOS_API " Disk driver modes."
|
||||
@raw_export_start BIOS_API
|
||||
@group DiskMode
|
||||
READ 0x00
|
||||
WRITE 0x01
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
@export_comment BIOS_API " Disk driver signals."
|
||||
@raw_export_start BIOS_API
|
||||
@group DiskSignals
|
||||
START 0x00
|
||||
CANCEL 0x01
|
||||
IGNORE 0xFF
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
@export_comment BIOS_API " Disk driver status."
|
||||
@raw_export_start BIOS_API
|
||||
@group DiskStatus
|
||||
FREE 0x00
|
||||
WRITING 0x01
|
||||
READING 0x02
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
@export_comment BIOS_API " Disk driver registers."
|
||||
@raw_export_start BIOS_API
|
||||
@group DiskRegisters
|
||||
SIGNAL 0x00
|
||||
MODE_SELECTOR 0x01
|
||||
DISK_SELECTOR 0x02
|
||||
SECTOR_SELECTOR 0x03
|
||||
ADDRESS_SELECTOR 0x05
|
||||
DATA_SIZE 0x07
|
||||
MEMORY_ADDRESS 0x09
|
||||
RO_STATUS 0x0B
|
||||
RO_CURRENT_DISK 0x0C
|
||||
RO_CURRENT_SECTOR 0x0D
|
||||
RO_CURRENT_ADDRESS 0x0F
|
||||
RO_REST_DATA_SIZE 0x11
|
||||
RO_MEMORY_ADDRESS 0x13
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
@export_comment BIOS_API " Disk driver data structure."
|
||||
@raw_export_start BIOS_API
|
||||
@struct DiskDriverData
|
||||
Mode:1 > 0x00
|
||||
Disk:1 > 0x00
|
||||
Sector:2 > 0x00, 0x00
|
||||
Address:2 > 0x00, 0x00
|
||||
DataSize:2 > 0x00, 0x00
|
||||
MemoryAddress:2 > 0x00, 0x00
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
## ===============================================================================================
|
||||
|
||||
.data
|
||||
$_bios_version_number_maj 0x00, 0x00
|
||||
$_bios_version_number_min 0x00, 0x04
|
||||
$_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 " |___/ "
|
||||
161
extra/dss/bios/display.dss
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
@guard _DISPLAY_INFO_DSS_
|
||||
|
||||
.code
|
||||
|
||||
_print_string_text16: ## _print_string(String* str, Text16VModeCell* cell)
|
||||
arg R1 ## @Param: String addr
|
||||
arg R2 ## @Param: Cell addr
|
||||
_print_string_text16_loop:
|
||||
mov R6, R2 ## Restore Cell addr
|
||||
movb *R6, *R1 ## Move next character into cell
|
||||
inc R1 ## Point address to next character
|
||||
addip R6, 3 ## Offset to X coord of cell
|
||||
movb R7, *R6 ## Store X coord in R7
|
||||
inc R7 ## Increment X coord
|
||||
movb *R6, R7 ## Store new X coord in cell
|
||||
mov R10, 0x21 ## int 0x30 parameter for print_char_text16
|
||||
mov R9, R2 ## int 0x30 parameter for text_cell address
|
||||
int 0x30 ## bios_video_int
|
||||
movb ACC, *R1 ## Copy current character in ACC
|
||||
jne $_print_string_text16_loop, 0 ## Jump if current character is not 0 (NULL_TERM)
|
||||
ret
|
||||
|
||||
|
||||
|
||||
_print_integer_text16: ## _print_integer_text16(int16_t number, TextCell16* cell)
|
||||
arg ACC ## @Param: number
|
||||
arg R2 ## @Param: cell
|
||||
mov R3, R2
|
||||
addip R3, 3 ## R3 is now a pointer to the X coord in the cell
|
||||
movb R6, *R3 ## Save original X coord in R6
|
||||
mov R1, 0
|
||||
jne $_print_integer_text16_loop, 0
|
||||
push 48 ## '0' ASCII is 48
|
||||
inc R1
|
||||
jmp $_print_integer_text16_loop_end
|
||||
_print_integer_text16_loop:
|
||||
jeq $_print_integer_text16_loop_end, 0
|
||||
divipu ACC, 10
|
||||
addipu RV, 48
|
||||
push RV
|
||||
inc R1
|
||||
jmp $_print_integer_text16_loop
|
||||
_print_integer_text16_loop_end:
|
||||
pop R4 ## Put next char in R4
|
||||
dec R1
|
||||
movb *R2, R4 ## Store next char in first byte of cell
|
||||
mov R10, 0x21 ## int 0x30 param for write vram
|
||||
mov R9, R2 ## int 0x30 param for textCell16
|
||||
int 0x30
|
||||
movb R5, *R3 ## Retrieve current X coord from cell
|
||||
inc R5 ## Increment X coord
|
||||
movb *R3, R5 ## Store new X coord in cell
|
||||
mov ACC, R1
|
||||
jne $_print_integer_text16_loop_end, 0
|
||||
movb *R3, R6 ## Restore original X coord
|
||||
ret
|
||||
|
||||
|
||||
|
||||
_print_integer_signle_color:
|
||||
mov R1, 0
|
||||
arg ACC
|
||||
jne $_print_integer_signle_color_loop, 0
|
||||
push 48 ## '0' ASCII is 48
|
||||
inc R1
|
||||
jmp $_print_integer_signle_color_loop_end
|
||||
_print_integer_signle_color_loop:
|
||||
jeq $_print_integer_signle_color_loop_end, 0
|
||||
divipu ACC, 10
|
||||
addipu RV, 48
|
||||
push RV
|
||||
inc R1
|
||||
jmp $_print_integer_signle_color_loop
|
||||
_print_integer_signle_color_loop_end:
|
||||
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_signle_color_loop_end, 0
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
_print_machine_info_signle_color:
|
||||
mov R9, $_bios_logo_2_line_1
|
||||
mov R10, 0x0C
|
||||
int 0x30 ## Print Next Logo Line
|
||||
mov R10, 0x02
|
||||
int 0x30 ## Print New Line
|
||||
mov R9, $_bios_logo_2_line_2
|
||||
mov R10, 0x0C
|
||||
int 0x30 ## Print Next Logo Line
|
||||
mov R10, 0x01
|
||||
mov R9, 32
|
||||
int 0x30 ## Print ' ' character
|
||||
mov R10, 0x0B
|
||||
int 0x30 ## Invert colors
|
||||
mov R10, 0x0C
|
||||
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, 0x0B
|
||||
int 0x30 ## Invert colors
|
||||
mov R10, 0x02
|
||||
int 0x30 ## Print New Line
|
||||
mov R9, $_bios_logo_2_line_3
|
||||
mov R10, 0x0C
|
||||
int 0x30 ## Print Next Logo Line
|
||||
mov R10, 0x0C
|
||||
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, 0x0C
|
||||
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, 0x0C
|
||||
int 0x30 ## Print Next Logo Line
|
||||
mov R10, 0x0C
|
||||
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, 0x0C
|
||||
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_signle_color_loop:
|
||||
inc R7
|
||||
mov R10, 0x0C
|
||||
int 0x30 ## Print Next Logo Line
|
||||
addip R9, 54 ## 54 is the length of a line
|
||||
mov R10, 0x02
|
||||
int 0x30 ## Print New Line
|
||||
jls $_print_machine_info_logo_signle_color_loop, R7
|
||||
ret
|
||||
182
extra/dss/bios/drivers.dss
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
@guard _DRIVERS_DSS_
|
||||
|
||||
.code
|
||||
|
||||
## ============================= BIOS Interrupt handler =============================
|
||||
_int_20_handler:
|
||||
mov ACC, R10
|
||||
jeq $_int_20_disk_interface, 0x0010
|
||||
jeq $_int_20_disk_interface_get_disk_list, 0x0011 ## TODO: Implement
|
||||
jeq $_int_20_disk_interface_load_from_ddd_blocking, 0x0012
|
||||
jeq $_int_20_set_new_interrupt_handler, 0x0000
|
||||
jeq $_int_20_clear_interrupt, 0x0001
|
||||
jmp $_int_20_end
|
||||
_int_20_disk_interface:
|
||||
movb [{MemoryAddresses.DISK_INTERFACE + 0x1}], *R9 ## Mode
|
||||
inc R9
|
||||
movb [{MemoryAddresses.DISK_INTERFACE + 0x2}], *R9 ## Disk
|
||||
inc R9
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + 0x3}], *R9 ## Sector
|
||||
addip R9, 2
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + 0x5}], *R9 ## Address
|
||||
addip R9, 2
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + 0x7}], *R9 ## Size
|
||||
addip R9, 2
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + 0x9}], *R9 ## Memory Address
|
||||
movb [MemoryAddresses.DISK_INTERFACE], DiskSignals.START ## Signal set to "Start Operation"
|
||||
jmp $_int_20_end
|
||||
_int_20_disk_interface_get_disk_list:
|
||||
jmp $_int_20_end
|
||||
_int_20_disk_interface_load_from_ddd_blocking:
|
||||
push R9 ## DDD Address
|
||||
push 1
|
||||
call $_disk_load_from_ddd_blocking
|
||||
jmp $_int_20_end
|
||||
_int_20_set_new_interrupt_handler:
|
||||
push R8 ## Interrupt Code
|
||||
push R9 ## Handler Address
|
||||
push 2
|
||||
call $_set_interrupt_vector_entry
|
||||
jmp $_int_20_end
|
||||
_int_20_clear_interrupt:
|
||||
push R9
|
||||
push 0x0000
|
||||
push 2
|
||||
call $_set_interrupt_vector_entry
|
||||
_int_20_end:
|
||||
rti
|
||||
## ==================================================================================
|
||||
|
||||
## ========================== BIOS Video Interrupt handler =========================
|
||||
_int_30_handler:
|
||||
mov ACC, R10
|
||||
jeq $_int_30_direct_print_char_text_single, 0x0001
|
||||
jeq $_int_30_direct_new_line_text_single, 0x0002
|
||||
jeq $_int_30_direct_print_string_text_single, 0x0003
|
||||
jeq $_int_30_direct_print_integer_text_single, 0x0004
|
||||
jeq $_int_30_store_integer_text_single, 0x0005
|
||||
jeq $_int_30_store_char_text_single, 0x0006
|
||||
jeq $_int_30_print_buffer_no_flush_text_single, 0x0007
|
||||
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_print_string_buffered, 0x000C
|
||||
|
||||
jeq $_int_30_write_vram_text16, 0x0021
|
||||
jeq $_int_30_print_string_text16, 0x0022
|
||||
jeq $_int_30_print_integer_text16, 0x0023
|
||||
jeq $_int_30_clear_screen_text16, 0x0024
|
||||
jeq $_int_30_scroll_text16, 0x0025
|
||||
|
||||
jeq $_int_30_clear_screen, 0x00E0
|
||||
jeq $_int_30_refresh_screen, 0x00E1
|
||||
jmp $_int_30_end
|
||||
|
||||
|
||||
_int_30_direct_print_char_text_single:
|
||||
movb [VGA_Registers.TEXT_SINGLE_CHAR], R9
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_CHAR
|
||||
jmp $_int_30_end
|
||||
_int_30_direct_new_line_text_single:
|
||||
movb [VGA_Registers.TEXT_SINGLE_CHAR], 10 ## New line char code
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.STORE_CHAR
|
||||
jmp $_int_30_end
|
||||
_int_30_direct_print_string_text_single:
|
||||
movb R1, *R9
|
||||
movb [VGA_Registers.TEXT_SINGLE_CHAR], R1
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_CHAR
|
||||
inc R9
|
||||
movb ACC, *R9
|
||||
jne $_int_30_direct_print_string_text_single, 0
|
||||
jmp $_int_30_end
|
||||
_int_30_direct_print_integer_text_single:
|
||||
mov reg(S_REG_1), Sig_VGA_Text_Single_Color.PRINT_CHAR
|
||||
push R9
|
||||
push 1
|
||||
call $_print_integer_signle_color
|
||||
jmp $_int_30_end
|
||||
_int_30_store_integer_text_single:
|
||||
mov reg(S_REG_1), Sig_VGA_Text_Single_Color.STORE_CHAR
|
||||
push R9
|
||||
push 1
|
||||
call $_print_integer_signle_color
|
||||
jmp $_int_30_end
|
||||
_int_30_store_char_text_single:
|
||||
movb [VGA_Registers.TEXT_SINGLE_CHAR], R9
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.STORE_CHAR
|
||||
jmp $_int_30_end
|
||||
_int_30_print_buffer_no_flush_text_single:
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_BUFF
|
||||
_int_30_print_buffer_and_flush_text_single:
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_FLUSH_BUFF
|
||||
jmp $_int_30_end
|
||||
_int_30_flush_buffer_text_single:
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.FLUSH_BUFF
|
||||
jmp $_int_30_end
|
||||
_int_30_store_string_text_single:
|
||||
movb R1, *R9
|
||||
movb [VGA_Registers.TEXT_SINGLE_CHAR], R1
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.STORE_CHAR
|
||||
inc R9
|
||||
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_print_string_buffered:
|
||||
mov [VGA_Registers.TEXT_SIGNLE_STR], R9
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_STRING
|
||||
jmp $_int_30_end
|
||||
|
||||
_int_30_write_vram_text16:
|
||||
movb [VGA_Registers.MEMORY_CONTROLLER_CHAR], *R9
|
||||
inc R9
|
||||
movb [VGA_Registers.MEMORY_CONTROLLER_FG_COL], *R9
|
||||
inc R9
|
||||
movb [VGA_Registers.MEMORY_CONTROLLER_BG_COL], *R9
|
||||
inc R9
|
||||
movb [VGA_Registers.MEMORY_CONTROLLER_X_BYTE], *R9
|
||||
inc R9
|
||||
movb [VGA_Registers.MEMORY_CONTROLLER_Y_BYTE], *R9
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_16_Color.WRITE_VRAM
|
||||
jmp $_int_30_end
|
||||
_int_30_print_string_text16:
|
||||
push R8 ## String addr
|
||||
push R9 ## TextCell16 addr
|
||||
push 2
|
||||
call $_print_string_text16
|
||||
jmp $_int_30_end
|
||||
_int_30_print_integer_text16:
|
||||
push R8 ## number
|
||||
push R9 ## TextCell16 addr
|
||||
push 2
|
||||
call $_print_integer_text16
|
||||
jmp $_int_30_end
|
||||
_int_30_clear_screen_text16:
|
||||
movb [VGA_Registers.MEMORY_CONTROLLER_CHAR], *R9
|
||||
inc R9
|
||||
movb [VGA_Registers.MEMORY_CONTROLLER_FG_COL], *R9
|
||||
inc R9
|
||||
movb [VGA_Registers.MEMORY_CONTROLLER_BG_COL], *R9
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_16_Color.FORCE_CLEAR_SCREEN
|
||||
jmp $_int_30_end
|
||||
_int_30_scroll_text16:
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_16_Color.SCROLL
|
||||
jmp $_int_30_end
|
||||
|
||||
_int_30_clear_screen:
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.CLEAR_SCREEN
|
||||
jmp $_int_30_end
|
||||
_int_30_refresh_screen:
|
||||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.REFRESH_SCREEN
|
||||
jmp $_int_30_end
|
||||
_int_30_end:
|
||||
rti
|
||||
## ==================================================================================
|
||||
37
extra/dss/bios/entry.dss
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
.load 0x0000 ## BIOS is mapped to address 0x0000 in memory
|
||||
.entry _bios_entry_point
|
||||
.fixed 4096, 0xFF ## BIOS Needs to be 4096 Bytes exactly
|
||||
|
||||
@include <data.dss>
|
||||
@include <utils.dss>
|
||||
@include <drivers.dss>
|
||||
@include <display.dss>
|
||||
|
||||
## ============================= BIOS Program =============================
|
||||
.code
|
||||
_bios_entry_point:
|
||||
movb [VGA_Registers.VIDEO_MODE], VGA_VideoModes.TEXT_SINGLE_COLOR ## Enable Text_Single_Color graphics mode
|
||||
mov FL, 0b0000000000000001 ## Zero the FL Register and enable interrupts
|
||||
mov reg(S_REG_OFFSET), 0x0000 ## Zero the offset register
|
||||
movb [{MemoryAddresses.INT_VEC + (0x20 * 3)}], 0xFF ## Setting up int 0x20 handler
|
||||
mov [{MemoryAddresses.INT_VEC + (0x20 * 3) + 1}], $_int_20_handler ## --
|
||||
|
||||
mov R10, 0x00 ## Setting up int 0x30 handler by using int 0x20 functionality
|
||||
mov R9, $_int_30_handler ## -Passing the handler's address
|
||||
mov R8, 0x30 ## -Passing the interrupt's code to setup
|
||||
int 0x20 ## -Calling int 0x20 with 0x00 as parameter, to set new handler up
|
||||
|
||||
push 0
|
||||
call $_print_machine_info_signle_color ## Print BIOS logo and machine info
|
||||
|
||||
## MBR Loading
|
||||
zflg Flags.InterruptsEnabled ## Disable interrupts
|
||||
push 0
|
||||
call $_load_mbr_data_block
|
||||
sflg Flags.InterruptsEnabled ## Enable interrupts
|
||||
## ----
|
||||
|
||||
%low INST_BIOS_NODE_TOGGLE 0x00 ## Disable BIOS Mode before leaving the BIOS
|
||||
jmp MemoryAddresses.MBR ## Jump to start of MBR in memory
|
||||
hlt ## Just in case somehow execution reaches this point
|
||||
## ========================================================================
|
||||
87
extra/dss/bios/utils.dss
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
@guard _UTILS_DSS_
|
||||
|
||||
.code
|
||||
|
||||
_disk_load_from_ddd_blocking: ## _disk_load_from_ddd_blocking(DiskDriverData* ddd)
|
||||
arg R1 ## @Param: ddd
|
||||
movb [{MemoryAddresses.DISK_INTERFACE + DiskRegisters.MODE_SELECTOR}], *R1
|
||||
inc R1
|
||||
movb [{MemoryAddresses.DISK_INTERFACE + DiskRegisters.DISK_SELECTOR}], *R1
|
||||
inc R1
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + DiskRegisters.SECTOR_SELECTOR}], *R1
|
||||
addip R1, 2
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + DiskRegisters.ADDRESS_SELECTOR}], *R1
|
||||
addip R1, 2
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + DiskRegisters.DATA_SIZE}], *R1
|
||||
addip R1, 2
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + DiskRegisters.MEMORY_ADDRESS}], *R1
|
||||
movb [{MemoryAddresses.DISK_INTERFACE + DiskRegisters.SIGNAL}], DiskSignals.START
|
||||
zflg Flags.InterruptsEnabled ## Disable interrupts
|
||||
_disk_load_from_ddd_blocking_wait_loop:
|
||||
## debug_profile_start 0xE0, DBGProfilerTime.MILLIS
|
||||
mov ACC, [{MemoryAddresses.DISK_INTERFACE + DiskRegisters.RO_STATUS}]
|
||||
## debug_profile_stop
|
||||
jne $_disk_load_from_ddd_blocking_wait_loop, DiskStatus.FREE
|
||||
sflg Flags.InterruptsEnabled ## Enable interrupts
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
_load_mbr_data_block:
|
||||
movb [{MemoryAddresses.DISK_INTERFACE + 0x1}], 0x00 ## Mode = Read
|
||||
movb R1, [CMOS_Settings.BOOT_DISK]
|
||||
movb [{MemoryAddresses.DISK_INTERFACE + 0x2}], R1 ## Disk = Default
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + 0x3}],0x0000 ## Sector = 0x0000
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + 0x5}],0x0000 ## Address = 0x0000 (Start of Disk)
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + 0x7}], 512 ## Size = 512 (Size of MBR is 512 bytes)
|
||||
mov [{MemoryAddresses.DISK_INTERFACE + 0x9}], MemoryAddresses.MBR ## MemoryAddress = MBR Address in memory
|
||||
movb [MemoryAddresses.DISK_INTERFACE], 0x00 ## Signal = Start
|
||||
_load_mbr_data_block_wait_loop:
|
||||
mov ACC, [{MemoryAddresses.DISK_INTERFACE + 0xB}] ## Moving <Status> register into ACC
|
||||
jne $_load_mbr_data_block_wait_loop, 0x00 ## If <Status> register not Free, loop around and wait
|
||||
ret
|
||||
|
||||
_calc_interrupt_vector_address:
|
||||
arg R1
|
||||
mul R1, 0x03 ## Multiply the interrupt code by 3 for memory alignment
|
||||
mov R1, ACC
|
||||
add R1, MemoryAddresses.INT_VEC ## Add Interrupt Vector base address to Interrupt code
|
||||
mov RV, ACC
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
_set_interrupt_vector_entry:
|
||||
arg R1
|
||||
push R1
|
||||
push 1
|
||||
call $_calc_interrupt_vector_address
|
||||
mov R1, RV
|
||||
arg ACC
|
||||
jeq $_set_interrupt_vector_entry_disable, 0x0000
|
||||
movb *R1, 0xFF
|
||||
jmp $_set_interrupt_vector_entry_end
|
||||
_set_interrupt_vector_entry_disable:
|
||||
movb *R1, 0x00
|
||||
_set_interrupt_vector_entry_end:
|
||||
inc R1
|
||||
mov *R1, ACC
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
_strlen:
|
||||
arg R1
|
||||
mov R2, 0
|
||||
_strlen_loop:
|
||||
movb ACC, *R1
|
||||
inc R1
|
||||
jeq $_strlen_loop_end, 0
|
||||
inc R2
|
||||
jmp $_strlen_loop
|
||||
_strlen_loop_end:
|
||||
mov RV, R2
|
||||
ret
|
||||
280
extra/dss/drake/bootsector.dss
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
.load 0x1740
|
||||
.entry _drake_bootsector_entry_point
|
||||
.fixed 5120, 0xFF
|
||||
|
||||
@include <../sdk/bios_api.dss>
|
||||
@include <../sdk/palette.dss>
|
||||
|
||||
@define OS_LOAD_ADDR 0x2C00
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
.data
|
||||
## Disk data structures
|
||||
$ddd <DiskDriverData>
|
||||
$dpt_block <DPTBlock>
|
||||
$bootstrap_block:32
|
||||
$bootstrap_addr:4
|
||||
|
||||
$textCell <Text16VModeCell>
|
||||
$counter 0x00
|
||||
$current_char 65
|
||||
|
||||
$dpt_version_str "DPT Version "
|
||||
$drake_version_str "Drake 0.2 -- "
|
||||
$invalid_dpt_block_str "Error: Invalid DPT Block..."
|
||||
$no_part_found_str "Error: No bootable partitions found..."
|
||||
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
.code
|
||||
## =========================================================================================================================
|
||||
_drake_bootsector_entry_point:
|
||||
## Load DPT block from disk 0
|
||||
push $ddd ## Empty DiskDriverData used to load from disk
|
||||
push $dpt_block ## Empty DPT Block to store the partition table
|
||||
push 2
|
||||
call $_load_dpt_block
|
||||
|
||||
## Enable Text16 Video Mode
|
||||
movb [VGA_Registers.VIDEO_MODE], VGA_VideoModes.TEXT_16_COLORS
|
||||
|
||||
## Validate DPT Block
|
||||
mov ACC, [$dpt_block]
|
||||
jne $_invalid_dpt_block, 0xF1CA
|
||||
|
||||
jmp $_endless_loop
|
||||
_invalid_dpt_block: ## TODO: Fix screen drawing on error
|
||||
push $invalid_dpt_block_str
|
||||
push 1
|
||||
call $_print_error_msg
|
||||
jmp $_main_end
|
||||
_endless_loop:
|
||||
|
||||
## Clear screen
|
||||
push DefaultPalette.Black
|
||||
push 1
|
||||
call $_clear_screen
|
||||
|
||||
## Print system info
|
||||
push 0
|
||||
call $_print_system_info
|
||||
|
||||
mov R10, $dpt_block.PartCount
|
||||
movb ACC, *R10
|
||||
jge $_no_partitions_found, 1
|
||||
|
||||
mov R10, $dpt_block.PartCount
|
||||
movb R10, *R10
|
||||
push $dpt_block.Entries
|
||||
push R10
|
||||
push $bootstrap_addr
|
||||
push 3
|
||||
call $_test_partitions
|
||||
mov ACC, RV
|
||||
jeq $_no_partitions_found, 0xFF
|
||||
|
||||
mov R1, $ddd
|
||||
mov R4, $bootstrap_addr
|
||||
|
||||
mov R3, R1 ## Copy $ddd address into R3
|
||||
movb *R1, DiskMode.READ ## $ddd.Mode
|
||||
inc R1
|
||||
movb *R1, 0x00 ## $ddd.Disk
|
||||
inc R1
|
||||
mov *R1, *R4 ## $ddd.Sector
|
||||
addip R1, 2
|
||||
addip R4, 2
|
||||
mov *R1, *R4 ## $ddd.Address
|
||||
addip R1, 2
|
||||
mov *R1, 1024 ## $ddd.DataSize
|
||||
addip R1, 2
|
||||
mov *R1, OS_LOAD_ADDR ## $ddd.MemoryAddress
|
||||
mov R9, R3 ## Move original $ddd address into R9 (for int 0x20)
|
||||
mov R10, 0x12 ## int 0x20 parameter for load_from_ddd_blocking
|
||||
int 0x20 ## Bios interrupt
|
||||
|
||||
jmp OS_LOAD_ADDR
|
||||
jmp $_main_end
|
||||
|
||||
_no_partitions_found:
|
||||
push $no_part_found_str
|
||||
push 1
|
||||
call $_print_error_msg
|
||||
jmp $_main_end
|
||||
|
||||
## jmp $_endless_loop
|
||||
_main_end:
|
||||
hlt
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_test_partitions: ## _test_partitions(DPTBlock* dpt_entries_block, (1 Byte) dpt_entries_count, (4 Bytes*) part_addr)
|
||||
arg R1 ## dpt_entries_block
|
||||
arg R2 ## dpt_entries_count
|
||||
arg R4 ## part_addr
|
||||
mov R3, 0 ## Entry counter
|
||||
_test_partitions_loop:
|
||||
push $ddd
|
||||
push $bootstrap_block
|
||||
push R3
|
||||
push 3
|
||||
call $_load_bootstrap_block
|
||||
mov ACC, $bootstrap_block
|
||||
mov ACC, *ACC
|
||||
jeq $_test_partitions_found, DPTBootPartStructure.ID_CODE
|
||||
inc R3
|
||||
mov ACC, R3
|
||||
jle $_test_partitions_not_found, R2
|
||||
jmp $_test_partitions_loop
|
||||
|
||||
_test_partitions_found:
|
||||
mov R10, R3
|
||||
mulip R10, DPTStructure.ENTRY_SIZE_B
|
||||
addip R10, R1
|
||||
mov *R4, *R10
|
||||
addip R4, 2
|
||||
addip R10, 2
|
||||
mov *R4, *R10
|
||||
mov R9, *R4
|
||||
addip R9, DPTBootPartStructure.HEADER_SIZE_B ## TODO: This doesn't take into account integer overflow, since it is a 32-Bit address
|
||||
mov *R4, R9
|
||||
mov RV, R3
|
||||
ret
|
||||
_test_partitions_not_found:
|
||||
mov *R4, 0xFFFF
|
||||
addip R4, 2
|
||||
mov *R4, 0xFFFF
|
||||
mov RV, 0xFF
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_load_bootstrap_block: ## _load_bootstrap_block(DiskDriverData* ddd, (32 Byte*) bootstrap_block, (1 Byte) dpt_entry)
|
||||
arg R1 ## @Param: ddd
|
||||
arg R2 ## @Param: bootstrap_block
|
||||
arg R7 ## @Param: dpt_entry
|
||||
mov R3, R1 ## Copy $ddd address into R3
|
||||
movb *R1, DiskMode.READ ## $ddd.Mode
|
||||
inc R1
|
||||
movb *R1, 0x00 ## $ddd.Disk
|
||||
inc R1
|
||||
mov R10, $dpt_block.Entries
|
||||
mulip R7, DPTStructure.ENTRY_SIZE_B
|
||||
addip R10, R7
|
||||
mov *R1, *R10 ## $ddd.Sector
|
||||
addip R1, 2
|
||||
addip R10, 2
|
||||
mov *R1, *R10 ## $ddd.Address
|
||||
addip R1, 2
|
||||
mov *R1, DPTBootPartStructure.HEADER_SIZE_B ## $ddd.DataSize
|
||||
addip R1, 2
|
||||
mov *R1, R2 ## $ddd.MemoryAddress
|
||||
mov R9, R3 ## Move original $ddd address into R9 (for int 0x20)
|
||||
mov R10, 0x12 ## int 0x20 parameter for load_from_ddd_blocking
|
||||
int 0x20 ## Bios interrupt
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_load_dpt_block: ## _load_dpt_block(DiskDriverData* ddd, DPTBlock* dpt_block)
|
||||
arg R1 ## @Param: ddd
|
||||
arg R2 ## @Param: dpt_block
|
||||
mov R3, R1 ## Copy $ddd address into R3
|
||||
movb *R1, DiskMode.READ ## $ddd.Mode
|
||||
inc R1
|
||||
movb *R1, 0x00 ## $ddd.Disk
|
||||
inc R1
|
||||
mov *R1, 0x0000 ## $ddd.Sector
|
||||
addip R1, 2
|
||||
mov *R1, 0x0200 ## $ddd.Address
|
||||
addip R1, 2
|
||||
mov *R1, 512 ## $ddd.DataSize
|
||||
addip R1, 2
|
||||
mov *R1, R2 ## $ddd.MemoryAddress
|
||||
mov R9, R3 ## Move original $ddd address into R9 (for int 0x20)
|
||||
mov R10, 0x12 ## int 0x20 parameter for load_from_ddd_blocking
|
||||
int 0x20 ## Bios interrupt
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_print_error_msg: ## _print_error_msg(string* error_msg)
|
||||
arg R1 ## @Param: error_msg
|
||||
## TODO: Clear the screen
|
||||
movb [$textCell.CoordX], 0
|
||||
movb [$textCell.CoordY], 1
|
||||
movb [$textCell.Foreground], DefaultPalette.Red
|
||||
movb [$textCell.Background], DefaultPalette.Black
|
||||
mov R10, 0x22
|
||||
mov R8, R1
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_print_system_info:
|
||||
movb [$textCell.CoordX], 0
|
||||
movb [$textCell.CoordY], 0
|
||||
movb [$textCell.Foreground], DefaultPalette.Green
|
||||
movb [$textCell.Background], DefaultPalette.Black
|
||||
mov R10, 0x22
|
||||
mov R8, $drake_version_str
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
movb [$textCell.CoordX], 13
|
||||
mov R10, 0x22
|
||||
mov R8, $dpt_version_str
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
movb [$textCell.CoordX], 26
|
||||
mov R10, 0x23
|
||||
movb R8, [{ $dpt_block + 2 }]
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
movb [$textCell.CoordX], 27
|
||||
movb [$textCell.Character], 0x2E
|
||||
mov R10, 0x21
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
movb [$textCell.CoordX], 28
|
||||
mov R10, 0x23
|
||||
movb R8, [{ $dpt_block + 3 }]
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
|
||||
|
||||
|
||||
## =========================================================================================================================
|
||||
_clear_screen: ## _clear_screen(int8_t color)
|
||||
arg R1
|
||||
movb [$textCell.Foreground], R1
|
||||
movb [$textCell.Background], R1
|
||||
movb [$textCell.Character], 0x20
|
||||
mov R10, 0x24
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
ret
|
||||
## =========================================================================================================================
|
||||
26
extra/dss/drake/loader.dss
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
.load 0x1380
|
||||
.entry _drake_loader_entry_point
|
||||
.fixed 512, 0x00
|
||||
|
||||
@include <../sdk/bios_api.dss>
|
||||
|
||||
.data
|
||||
$ddd <DiskDriverData>
|
||||
|
||||
|
||||
.code
|
||||
_drake_loader_entry_point:
|
||||
mov [$ddd.Mode], DiskMode.READ
|
||||
mov [$ddd.Disk], 0x00
|
||||
mov [$ddd.Sector], 0x0000
|
||||
mov [$ddd.Address], 0x0400
|
||||
mov [$ddd.DataSize], 5120
|
||||
mov [$ddd.MemoryAddress], MemoryAddresses.RAM
|
||||
|
||||
mov R9, $ddd
|
||||
mov R10, 0x12
|
||||
int 0x20
|
||||
|
||||
jmp MemoryAddresses.RAM
|
||||
hlt
|
||||
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
.load 0x1A40
|
||||
|
||||
##@struct Rectangle {
|
||||
## width:2,
|
||||
## height:2,
|
||||
## x:2,
|
||||
## y:2
|
||||
##
|
||||
## ## Static properties
|
||||
## StructSize
|
||||
##}
|
||||
|
||||
.data
|
||||
$cursor_pos 0x00, 0x00
|
||||
$color 0x02
|
||||
$current_video_addr 0x07, 0xBC
|
||||
|
||||
$string "Hello World!!"
|
||||
|
||||
## $rect => Rectangle
|
||||
|
||||
.code
|
||||
debug_break
|
||||
infinite_loop:
|
||||
push 0
|
||||
call $clear_screen
|
||||
|
||||
## mov $rect.x, 200
|
||||
|
||||
## debug_break
|
||||
|
||||
push $string
|
||||
push 1
|
||||
call $print_string
|
||||
|
||||
jmp $infinite_loop
|
||||
hlt
|
||||
|
||||
|
||||
print_string:
|
||||
mov R1, *PP
|
||||
dec PP
|
||||
dec PP
|
||||
|
||||
push R1
|
||||
push 1
|
||||
call $strlen
|
||||
mov R2, RV
|
||||
|
||||
push 65
|
||||
push 1
|
||||
call $print_char
|
||||
ret
|
||||
|
||||
|
||||
strlen:
|
||||
mov R1, *PP
|
||||
dec PP
|
||||
dec PP
|
||||
mov R2, 0
|
||||
_strlen_loop:
|
||||
movb ACC, *R1
|
||||
jeq $_strlen_end_loop, 0
|
||||
inc R2
|
||||
inc R1
|
||||
jmp $_strlen_loop
|
||||
_strlen_end_loop:
|
||||
mov RV, R2
|
||||
ret
|
||||
|
||||
print_char:
|
||||
mov R2, *PP
|
||||
dec PP
|
||||
dec PP
|
||||
mov R1, [$current_video_addr]
|
||||
mov R3, [$cursor_pos]
|
||||
mul R3, 2
|
||||
mov R3, ACC
|
||||
add R1, R3
|
||||
mov R1, ACC
|
||||
movb *R1, R2
|
||||
inc R1
|
||||
movb *R1, [$color]
|
||||
mov R3, [$cursor_pos]
|
||||
inc R3
|
||||
mov [$cursor_pos], R3
|
||||
ret
|
||||
|
||||
clear_screen:
|
||||
mov R10, 0x00
|
||||
int 0x30
|
||||
ret
|
||||
|
||||
.fixed 512, 0x00
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
.load 0x1680
|
||||
|
||||
.code
|
||||
jmp 0x1A40
|
||||
hlt
|
||||
|
||||
.fixed 512, 0x00
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
.load 0x1A40
|
||||
|
||||
.data
|
||||
$v1 0x00, 0x01
|
||||
$v2 0x00, 0x01
|
||||
$v3 0x00, 0x01, 0x00, 0x01, 0x00, 0x01
|
||||
|
||||
.code
|
||||
mov R1, 0xAA
|
||||
mov R2, 0xBB
|
||||
mov R3, 0xCC
|
||||
debug_break
|
||||
hlt
|
||||
|
||||
.fixed 512, 0x00
|
||||
132
extra/dss/sdk/ascii.dss
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
@guard _ASCII_DSS_
|
||||
|
||||
@group ASCII
|
||||
NULL 0x00
|
||||
SOH 0x01
|
||||
STX 0x02
|
||||
ETX 0x03
|
||||
EOT 0x04
|
||||
ENQ 0x05
|
||||
ACK 0x06
|
||||
BEL 0x07
|
||||
BS 0x08
|
||||
HT 0x09
|
||||
LF 0x0A
|
||||
VT 0x0B
|
||||
FF 0x0C
|
||||
CR 0x0D
|
||||
SO 0x0E
|
||||
SI 0x0F
|
||||
DLE 0x10
|
||||
DC1 0x11
|
||||
DC2 0x12
|
||||
DC3 0x13
|
||||
DC4 0x14
|
||||
NAK 0x15
|
||||
SYN 0x16
|
||||
ETB 0x17
|
||||
CAN 0x18
|
||||
EM 0x19
|
||||
SUB 0x1A
|
||||
ESC 0x1B
|
||||
FS 0x1C
|
||||
GS 0x1D
|
||||
RS 0x1E
|
||||
US 0x1F
|
||||
SPACE 0x20
|
||||
EXCLAMATION_MARK 0x21
|
||||
DOUBLE_QUOTE 0x22
|
||||
HASH 0x23
|
||||
DOLLAR_SIGN 0x24
|
||||
PERCENT_SIGN 0x25
|
||||
AMPERSAND 0x26
|
||||
SINGLE_QUOTE 0x27
|
||||
OPEN_PARENTHESIS 0x28
|
||||
CLOSE_PARENTHESIS 0x29
|
||||
ASTERISK 0x2A
|
||||
PLUS_SIGN 0x2B
|
||||
COMMA 0x2C
|
||||
HYPHEN 0x2D
|
||||
PERIOD 0x2E
|
||||
FORWARD_SLASH 0x2F
|
||||
DIGIT_0 0x30
|
||||
DIGIT_1 0x31
|
||||
DIGIT_2 0x32
|
||||
DIGIT_3 0x33
|
||||
DIGIT_4 0x34
|
||||
DIGIT_5 0x35
|
||||
DIGIT_6 0x36
|
||||
DIGIT_7 0x37
|
||||
DIGIT_8 0x38
|
||||
DIGIT_9 0x39
|
||||
COLON 0x3A
|
||||
SEMICOLON 0x3B
|
||||
LESS_THAN_SIGN 0x3C
|
||||
EQUALS_SIGN 0x3D
|
||||
GREATER_THAN_SIGN 0x3E
|
||||
QUESTION_MARK 0x3F
|
||||
AT_SIGN 0x40
|
||||
UPPERCASE_A 0x41
|
||||
UPPERCASE_B 0x42
|
||||
UPPERCASE_C 0x43
|
||||
UPPERCASE_D 0x44
|
||||
UPPERCASE_E 0x45
|
||||
UPPERCASE_F 0x46
|
||||
UPPERCASE_G 0x47
|
||||
UPPERCASE_H 0x48
|
||||
UPPERCASE_I 0x49
|
||||
UPPERCASE_J 0x4A
|
||||
UPPERCASE_K 0x4B
|
||||
UPPERCASE_L 0x4C
|
||||
UPPERCASE_M 0x4D
|
||||
UPPERCASE_N 0x4E
|
||||
UPPERCASE_O 0x4F
|
||||
UPPERCASE_P 0x50
|
||||
UPPERCASE_Q 0x51
|
||||
UPPERCASE_R 0x52
|
||||
UPPERCASE_S 0x53
|
||||
UPPERCASE_T 0x54
|
||||
UPPERCASE_U 0x55
|
||||
UPPERCASE_V 0x56
|
||||
UPPERCASE_W 0x57
|
||||
UPPERCASE_X 0x58
|
||||
UPPERCASE_Y 0x59
|
||||
UPPERCASE_Z 0x5A
|
||||
OPEN_SQUARE_BRACKET 0x5B
|
||||
BACKSLASH 0x5C
|
||||
CLOSE_SQUARE_BRACKET 0x5D
|
||||
CARET 0x5E
|
||||
UNDERSCORE 0x5F
|
||||
GRAVE_ACCENT 0x60
|
||||
LOWERCASE_A 0x61
|
||||
LOWERCASE_B 0x62
|
||||
LOWERCASE_C 0x63
|
||||
LOWERCASE_D 0x64
|
||||
LOWERCASE_E 0x65
|
||||
LOWERCASE_F 0x66
|
||||
LOWERCASE_G 0x67
|
||||
LOWERCASE_H 0x68
|
||||
LOWERCASE_I 0x69
|
||||
LOWERCASE_J 0x6A
|
||||
LOWERCASE_K 0x6B
|
||||
LOWERCASE_L 0x6C
|
||||
LOWERCASE_M 0x6D
|
||||
LOWERCASE_N 0x6E
|
||||
LOWERCASE_O 0x6F
|
||||
LOWERCASE_P 0x70
|
||||
LOWERCASE_Q 0x71
|
||||
LOWERCASE_R 0x72
|
||||
LOWERCASE_S 0x73
|
||||
LOWERCASE_T 0x74
|
||||
LOWERCASE_U 0x75
|
||||
LOWERCASE_V 0x76
|
||||
LOWERCASE_W 0x77
|
||||
LOWERCASE_X 0x78
|
||||
LOWERCASE_Y 0x79
|
||||
LOWERCASE_Z 0x7A
|
||||
OPEN_CURLY_BRACE 0x7B
|
||||
VERTICAL_BAR 0x7C
|
||||
CLOSE_CURLY_BRACE 0x7D
|
||||
TILDE 0x7E
|
||||
DELETE 0x7F
|
||||
@end
|
||||
226
extra/dss/sdk/bios_api.dss
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
## --
|
||||
## -- This file is automatically generated by the DragonAssembler (version 0.4.1650)
|
||||
## -- Please do not modify this file in any way.
|
||||
## --
|
||||
|
||||
## These are the base addresses of the memory map.
|
||||
@group MemoryAddresses
|
||||
MBR 0x1380
|
||||
INT_VEC 0x1080
|
||||
DISK_INTERFACE 0x1580
|
||||
RAM 0x1740
|
||||
CMOS 0x1000
|
||||
VGA 0x1600
|
||||
KEYBOARD 0x1280
|
||||
@end
|
||||
## --
|
||||
|
||||
## These are the addresses of CMOS data.
|
||||
@group CMOS_Settings
|
||||
MEM_START { MemoryAddresses.CMOS + 0x0000 }
|
||||
MEM_SIZE { MemoryAddresses.CMOS + 0x0002 }
|
||||
CLOCK_SPEED { MemoryAddresses.CMOS + 0x0004 }
|
||||
SCREEN_REDRAW_RATE { MemoryAddresses.CMOS + 0x0006 }
|
||||
SCREEN_WIDTH { MemoryAddresses.CMOS + 0x0007 }
|
||||
SCREEN_HEIGHT { MemoryAddresses.CMOS + 0x0009 }
|
||||
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
|
||||
STACK_SIZE { MemoryAddresses.CMOS + 0x0011 }
|
||||
DISK_LIST { MemoryAddresses.CMOS + 0x007E }
|
||||
@end
|
||||
## --
|
||||
|
||||
## These are the FLAG addresses.
|
||||
@group Flags
|
||||
InterruptsEnabled 0x00
|
||||
OffsetModeEnabled 0x01
|
||||
@end
|
||||
## --
|
||||
|
||||
## These are the Hardware Interrupt codes of this machine.
|
||||
@group HW_Int
|
||||
DISK_INTERFACE_FINISHED 0x80
|
||||
KEY_PRESSED 0xA0
|
||||
KEY_RELEASED 0xA1
|
||||
TEXT_ENTERED 0xA2
|
||||
TEXT16_SCREEN_REFRESHED 0xE0
|
||||
@end
|
||||
## --
|
||||
|
||||
## These are the memory-mapped registers used to interact with the video card's interface.
|
||||
@group VGA_Registers
|
||||
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
|
||||
CLEAR_COLOR { MemoryAddresses.VGA + 0x0001 }
|
||||
PALETTE { MemoryAddresses.VGA + 0x0002 }
|
||||
SIGNAL { MemoryAddresses.VGA + 0x0003 }
|
||||
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
|
||||
TEXT_SIGNLE_INVERT { MemoryAddresses.VGA + 0x0005 }
|
||||
TEXT_SIGNLE_STR { MemoryAddresses.VGA + 0x0006 }
|
||||
FLAGS { MemoryAddresses.VGA + 0x007E }
|
||||
MEMORY_CONTROLLER_X { MemoryAddresses.VGA + 0x0080 }
|
||||
MEMORY_CONTROLLER_X_BYTE { MemoryAddresses.VGA + 0x0080 + 1 }
|
||||
MEMORY_CONTROLLER_Y { MemoryAddresses.VGA + 0x0082 }
|
||||
MEMORY_CONTROLLER_Y_BYTE { MemoryAddresses.VGA + 0x0082 + 1 }
|
||||
MEMORY_CONTROLLER_CHAR { MemoryAddresses.VGA + 0x0084 }
|
||||
MEMORY_CONTROLLER_BG_COL { MemoryAddresses.VGA + 0x0085 }
|
||||
MEMORY_CONTROLLER_FG_COL { MemoryAddresses.VGA + 0x0086 }
|
||||
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
|
||||
@end
|
||||
## --
|
||||
|
||||
## These are the memory-mapped registers used to interact with the keyboard's interface.
|
||||
@group Keyboard_Registers
|
||||
MODIFIERS_BITFIELD { MemoryAddresses.KEYBOARD + 0x0000 }
|
||||
KEYCODE { MemoryAddresses.KEYBOARD + 0x0002 }
|
||||
@end
|
||||
## --
|
||||
|
||||
## These are the different Video Modes that the video card supports.
|
||||
@group VGA_VideoModes
|
||||
TEXT_SINGLE_COLOR 0x00
|
||||
TEXT_16_COLORS 0x01
|
||||
@end
|
||||
## --
|
||||
|
||||
## These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode.
|
||||
@group Sig_VGA_Text_Single_Color
|
||||
CONTINUE 0x00
|
||||
PRINT_CHAR 0x02
|
||||
STORE_CHAR 0x03
|
||||
PRINT_FLUSH_BUFF 0x04
|
||||
FLUSH_BUFF 0x05
|
||||
PRINT_BUFF 0x06
|
||||
PRINT_STRING 0x07
|
||||
REFRESH_SCREEN 0xE0
|
||||
CLEAR_SCREEN 0xE1
|
||||
REDRAW_SCREEN 0xE2
|
||||
@end
|
||||
## --
|
||||
|
||||
## These are signals used to comunicate with the video card's interface, when in TEXT16_COLOR mode.
|
||||
@group Sig_VGA_Text_16_Color
|
||||
CONTINUE 0x00
|
||||
SWAP_BUFFERS 0x10
|
||||
WRITE_VRAM 0x11
|
||||
SCROLL 0x12
|
||||
FORCE_REFRESH_SCREEN 0xE0
|
||||
FORCE_CLEAR_SCREEN 0xE1
|
||||
FORCE_REDRAW_SCREEN 0xE2
|
||||
@end
|
||||
## --
|
||||
|
||||
## Structure of a DPT (Dragon Partition Table).
|
||||
@group DPTStructure
|
||||
DISK_ADDR 0x0200
|
||||
ENTRIES_START 0x000C
|
||||
ENTRY_START_ADDR 0x0000
|
||||
ENTRY_PART_SIZE 0x0004
|
||||
ENTRY_FLAGS 0x0008
|
||||
ENTRY_PART_LBL 0x0024
|
||||
ID_CODE 0xF1CA
|
||||
ENTRY_SIZE_B 100
|
||||
@end
|
||||
## --
|
||||
|
||||
## Structure of a Bootable partitions (Dragon Partition Table).
|
||||
@group DPTBootPartStructure
|
||||
ID_ADDR 0x0000
|
||||
CODE_START 0x0020
|
||||
ID_CODE 0xF1C4
|
||||
CODE_SIZE_B 1024
|
||||
HEADER_SIZE_B 32
|
||||
CODE_LOAD_ADDR 0x2C00
|
||||
@end
|
||||
## --
|
||||
|
||||
## Structure to store a DPT block.
|
||||
@struct DPTBlock
|
||||
ID:2
|
||||
VersionMaj:1
|
||||
VersionMin:1
|
||||
PartCount:1
|
||||
Reserved:7
|
||||
Entries:500
|
||||
@end
|
||||
## --
|
||||
|
||||
## Structure to store a DPT Partition block.
|
||||
@struct DPTPartitionBlock
|
||||
StartAddress:4
|
||||
Size:4
|
||||
Flags:2
|
||||
Reserved:26
|
||||
Label:64
|
||||
@end
|
||||
## --
|
||||
|
||||
## Structure to store a character cell for the Text16-Video-Mode.
|
||||
@struct Text16VModeCell
|
||||
Character:1
|
||||
Foreground:1
|
||||
Background:1
|
||||
CoordX:1
|
||||
CoordY:1
|
||||
@end
|
||||
## --
|
||||
|
||||
## Debugger Profiler time units.
|
||||
@group DBGProfilerTime
|
||||
MILLIS 0x00
|
||||
SECS 0x01
|
||||
MICROS 0x02
|
||||
NANOS 0x03
|
||||
@end
|
||||
## --
|
||||
|
||||
## Disk driver modes.
|
||||
@group DiskMode
|
||||
READ 0x00
|
||||
WRITE 0x01
|
||||
@end
|
||||
## --
|
||||
|
||||
## Disk driver signals.
|
||||
@group DiskSignals
|
||||
START 0x00
|
||||
CANCEL 0x01
|
||||
IGNORE 0xFF
|
||||
@end
|
||||
## --
|
||||
|
||||
## Disk driver status.
|
||||
@group DiskStatus
|
||||
FREE 0x00
|
||||
WRITING 0x01
|
||||
READING 0x02
|
||||
@end
|
||||
## --
|
||||
|
||||
## Disk driver registers.
|
||||
@group DiskRegisters
|
||||
SIGNAL 0x00
|
||||
MODE_SELECTOR 0x01
|
||||
DISK_SELECTOR 0x02
|
||||
SECTOR_SELECTOR 0x03
|
||||
ADDRESS_SELECTOR 0x05
|
||||
DATA_SIZE 0x07
|
||||
MEMORY_ADDRESS 0x09
|
||||
RO_STATUS 0x0B
|
||||
RO_CURRENT_DISK 0x0C
|
||||
RO_CURRENT_SECTOR 0x0D
|
||||
RO_CURRENT_ADDRESS 0x0F
|
||||
RO_REST_DATA_SIZE 0x11
|
||||
RO_MEMORY_ADDRESS 0x13
|
||||
@end
|
||||
## --
|
||||
|
||||
## Disk driver data structure.
|
||||
@struct DiskDriverData
|
||||
Mode:1 > 0x00
|
||||
Disk:1 > 0x00
|
||||
Sector:2 > 0x00, 0x00
|
||||
Address:2 > 0x00, 0x00
|
||||
DataSize:2 > 0x00, 0x00
|
||||
MemoryAddress:2 > 0x00, 0x00
|
||||
@end
|
||||
## --
|
||||
|
||||
156
extra/dss/sdk/keycodes.dss
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
@guard _KEYCODES_DSS_
|
||||
|
||||
@group KeyCodes
|
||||
Delete 0x7F
|
||||
Return 0x0D
|
||||
Escape 0x1B
|
||||
Backspace 0x08
|
||||
Tab 0x09
|
||||
Spacebar 0x20
|
||||
ExclamationMark 0x21
|
||||
DoubleQuote 0x22
|
||||
Hash 0x23
|
||||
Percent 0x25
|
||||
DollarSign 0x24
|
||||
Ampersand 0x26
|
||||
SingleQuote 0x27
|
||||
LeftParenthesis 0x28
|
||||
RightParenthesis 0x29
|
||||
Asterisk 0x2A
|
||||
Plus 0x2B
|
||||
Comma 0x2C
|
||||
Minus 0x2D
|
||||
Period 0x2E
|
||||
ForwardSlash 0x2F
|
||||
Num0 0x30
|
||||
Num1 0x31
|
||||
Num2 0x32
|
||||
Num3 0x33
|
||||
Num4 0x34
|
||||
Num5 0x35
|
||||
Num6 0x36
|
||||
Num7 0x37
|
||||
Num8 0x38
|
||||
Num9 0x39
|
||||
Colon 0x3A
|
||||
Semicolon 0x3B
|
||||
LessThan 0x3C
|
||||
Equals 0x3D
|
||||
GreaterThan 0x3E
|
||||
QuestionMark 0x3F
|
||||
AtSign 0x40
|
||||
|
||||
UpperCase_A 0x41
|
||||
UpperCase_B 0x42
|
||||
UpperCase_C 0x43
|
||||
UpperCase_D 0x44
|
||||
UpperCase_E 0x45
|
||||
UpperCase_F 0x46
|
||||
UpperCase_G 0x47
|
||||
UpperCase_H 0x48
|
||||
UpperCase_I 0x49
|
||||
UpperCase_J 0x4A
|
||||
UpperCase_K 0x4B
|
||||
UpperCase_L 0x4C
|
||||
UpperCase_M 0x4D
|
||||
UpperCase_N 0x4E
|
||||
UpperCase_O 0x4F
|
||||
UpperCase_P 0x50
|
||||
UpperCase_Q 0x51
|
||||
UpperCase_R 0x52
|
||||
UpperCase_S 0x53
|
||||
UpperCase_T 0x54
|
||||
UpperCase_U 0x55
|
||||
UpperCase_V 0x56
|
||||
UpperCase_W 0x57
|
||||
UpperCase_X 0x58
|
||||
UpperCase_Y 0x59
|
||||
UpperCase_Z 0x5A
|
||||
|
||||
LeftBracket 0x5B
|
||||
BackSlash 0x5C
|
||||
RightBracket 0x5D
|
||||
Caret 0x5E
|
||||
Underscore 0x5F
|
||||
BackQuote 0x60
|
||||
LowerCase_a 0x61
|
||||
LowerCase_b 0x62
|
||||
LowerCase_c 0x63
|
||||
LowerCase_d 0x64
|
||||
LowerCase_e 0x65
|
||||
LowerCase_f 0x66
|
||||
LowerCase_g 0x67
|
||||
LowerCase_h 0x68
|
||||
LowerCase_i 0x69
|
||||
LowerCase_j 0x6A
|
||||
LowerCase_k 0x6B
|
||||
LowerCase_l 0x6C
|
||||
LowerCase_m 0x6D
|
||||
LowerCase_n 0x6E
|
||||
LowerCase_o 0x6F
|
||||
LowerCase_p 0x70
|
||||
LowerCase_q 0x71
|
||||
LowerCase_r 0x72
|
||||
LowerCase_s 0x73
|
||||
LowerCase_t 0x74
|
||||
LowerCase_u 0x75
|
||||
LowerCase_v 0x76
|
||||
LowerCase_w 0x77
|
||||
LowerCase_x 0x78
|
||||
LowerCase_y 0x79
|
||||
LowerCase_z 0x7A
|
||||
|
||||
LeftCTRL 0x0100
|
||||
RightCTRL 0x0101
|
||||
LeftALT 0x0102
|
||||
RightALT 0x0103
|
||||
LeftShift 0x0104
|
||||
RightShift 0x0105
|
||||
|
||||
KeyPadDivide 0x0106
|
||||
KeyPadMultiply 0x0107
|
||||
KeyPadMinus 0x0108
|
||||
KeyPadPlus 0x0109
|
||||
KeyPadEnter 0x010A
|
||||
KeyPad1 0x010B
|
||||
KeyPad2 0x010C
|
||||
KeyPad3 0x010D
|
||||
KeyPad4 0x010E
|
||||
KeyPad5 0x010F
|
||||
KeyPad6 0x0110
|
||||
KeyPad7 0x0111
|
||||
KeyPad8 0x0112
|
||||
KeyPad9 0x0113
|
||||
KeyPad0 0x0114
|
||||
KeyPadPeriod 0x0115
|
||||
|
||||
PrintScreen 0x0116
|
||||
Insert 0x0117
|
||||
Home 0x0118
|
||||
PageUp 0x0119
|
||||
End 0x011A
|
||||
PageDown 0x011B
|
||||
RightArrow 0x011C
|
||||
LeftArrow 0x011D
|
||||
DownArrow 0x011E
|
||||
UpArrow 0x011F
|
||||
CapsLock 0x0120
|
||||
NumLock 0x0121
|
||||
ScrollLock 0x0122
|
||||
|
||||
F1 0x0123
|
||||
F2 0x0124
|
||||
F3 0x0125
|
||||
F4 0x0126
|
||||
F5 0x0127
|
||||
F6 0x0128
|
||||
F7 0x0129
|
||||
F8 0x012A
|
||||
F9 0x012B
|
||||
F10 0x012C
|
||||
F11 0x012D
|
||||
F12 0x012E
|
||||
|
||||
LeftSuper 0x012F
|
||||
RightSuper 0x0130
|
||||
@end
|
||||
45
extra/dss/sdk/palette.dss
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
@guard _PALETTE_DSS_
|
||||
|
||||
@group DefaultPalette
|
||||
Black 0x00
|
||||
Gray 0x01
|
||||
White 0x02
|
||||
Red 0x03
|
||||
Pink 0x04
|
||||
Brown 0x05
|
||||
DarkOrange 0x06
|
||||
Orange 0x07
|
||||
Yellow 0x08
|
||||
DarkGreen 0x09
|
||||
Green 0x0A
|
||||
Lime 0x0B
|
||||
DarkBlue 0x0C
|
||||
Blue 0x0D
|
||||
LightBlue 0x0E
|
||||
Sky 0x0F
|
||||
@end
|
||||
|
||||
.code
|
||||
|
||||
_draw_palette: ## _draw_palette(word x, word y)
|
||||
arg R1
|
||||
movb [$textCell.CoordX], R1
|
||||
arg R2
|
||||
movb [$textCell.CoordY], R2
|
||||
movb [$textCell.Character], 0x20
|
||||
movb [$textCell.Foreground], 0
|
||||
mov R5, 0
|
||||
_draw_palette_loop:
|
||||
movb [$textCell.Background], R5
|
||||
movb R6, [$textCell.CoordX]
|
||||
inc R6
|
||||
movb [$textCell.CoordX], R6
|
||||
|
||||
mov R10, 0x21
|
||||
mov R9, $textCell
|
||||
int 0x30
|
||||
|
||||
inc R5
|
||||
mov ACC, R5
|
||||
jge $_draw_palette_loop, 15
|
||||
ret
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
.load 0x1A40
|
||||
|
||||
.code
|
||||
mov R1, 0xABCD
|
||||
debug_break
|
||||
hlt
|
||||
|
||||
.fixed 512, 0x00
|
||||
0
extra/font.bmp
Normal file → Executable file
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
BIN
extra/icon.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
260
extra/info/info
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
#==========================================================================================================================================
|
||||
# Memory Map
|
||||
#==========================================================================================================================================
|
||||
0x0000 BIOS (4096 Bytes) (write to this section is disabled)
|
||||
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
|
||||
DisplayRedrawRate: (1 bytes) 0x0006
|
||||
ScreenWidth: (2 bytes) 0x0007
|
||||
ScreenHeight: (2 bytes) 0x0009
|
||||
BootDisk: 0x0010
|
||||
|
||||
DiskList: (2 bytes) 0x007E
|
||||
0x107F
|
||||
-------
|
||||
0x1080 INTERRUPT VECTOR (512 Bytes)
|
||||
Status: 1 Byte
|
||||
0xFF: Enabled
|
||||
0x00: Disabled
|
||||
Handler Address: 2 Byte
|
||||
...Repeat...
|
||||
0x127F
|
||||
-------
|
||||
0x1280 KEYBOARD MAPPING (224 Bytes) (write to this section is only allowed in BIOS Mode)
|
||||
0x00: Modifiers (2 bytes)
|
||||
0b00000000.00000001: Left Shift
|
||||
0b00000000.00000010: Left Ctrl
|
||||
0b00000000.00000100: Left Alt
|
||||
0b00000000.00001000: Left Super
|
||||
0b00000000.00010000: Right Shift
|
||||
0b00000000.00100000: Right Control
|
||||
0b00000000.01000000: Right Alt
|
||||
0b00000000.10000000: Right Super
|
||||
0b00000001.00000000: Caps Lock
|
||||
0b00000010.00000000: Num Lock
|
||||
0b00000100.00000000: Scroll Lock
|
||||
0x02: KeyCode (2 bytes)
|
||||
0x135F
|
||||
-------
|
||||
0x1360 MOUSE MAPPING (32 Bytes)
|
||||
0x137F
|
||||
-------
|
||||
0x1380 BOOTLOADER (512 Bytes)
|
||||
0x157F
|
||||
-------
|
||||
0x1580 DISK INTERFACE (128 Bytes)
|
||||
Read/Write:
|
||||
Signal: 1 Byte
|
||||
0x00: Start Operation
|
||||
0x01: Cancel Current Operation
|
||||
0xFF: Ignore
|
||||
Mode: 1 Byte
|
||||
0x00: Read
|
||||
0x01: Write
|
||||
Disk: 1 Byte
|
||||
Sector: 2 Bytes
|
||||
Address: 2 Bytes
|
||||
DataSize: 2 Bytes
|
||||
DataAddress: 2 Byte
|
||||
ReadOnly:
|
||||
Status: 1 Byte
|
||||
0x00: Free
|
||||
0x01: Writing
|
||||
0x02: Reading
|
||||
CurrentDisk: 1 Byte
|
||||
CurrentSector: 2 Bytes
|
||||
CurrentAddress: 2 Bytes
|
||||
RestDataSize: 2 Bytes
|
||||
SourceData: 2 Bytes
|
||||
Free: 107 Byte
|
||||
0x15FF
|
||||
-------
|
||||
0x1600 VIDEO CARD INTERFACE (256 Bytes)
|
||||
0x00: Video Mode (1 Byte)
|
||||
0x00: Text Single Color
|
||||
0x01: Text 16-color
|
||||
# 0x02: Text 256-color
|
||||
# 0x03: Text True Color Mode
|
||||
# 0x04: GFX Single Color
|
||||
# 0x05: GFX 16-color
|
||||
# 0x06: GFX 256-color
|
||||
# 0x07: GFX True Color Mode
|
||||
0x01: Clear Color (1 Byte)
|
||||
0x02: Palette (1 Byte)
|
||||
0x03: Signal (1 Byte)
|
||||
0x00: Continue
|
||||
|
||||
0x02: Text Single Color - Direct Print Character
|
||||
0x03: Text Single Color - Store character in buffer
|
||||
0x04: Text SIngle Color - Direct Print buffer & Flush Buffer
|
||||
0x05: Text Single Color - Flush Buffer
|
||||
0x06: Text Single Color - Print Buffer Without Flushing
|
||||
0x07: Text Single Color - Print Buffered String
|
||||
|
||||
0x11: Text 16 Colors - Write Memory
|
||||
|
||||
0xE0: Refresh Screen
|
||||
0xE1: Clear Screen
|
||||
0xE2: Redraw Screen
|
||||
0x04: Text Single Color Character (1 Byte)
|
||||
0x05: Text Single Color Inverted colors (1 Byte)
|
||||
0x06: (2 bytes) Text Single Color Buffered String Address
|
||||
|
||||
0x7E: Flags (2 Bytes)
|
||||
0b00000000.00000001: Double Buffering Enabled
|
||||
0b00000000.00000010: Disable Screen Redraw
|
||||
0x80: Memory Controller
|
||||
0x80: XCoordinate (2 Bytes)
|
||||
0x84: YCoordinate (2 Bytes)
|
||||
0x88: Character (1 Byte)
|
||||
0x09: Foreground (1 Byte)
|
||||
0x8A: Background (1 Byte)
|
||||
|
||||
(VRAM Memory Cell: Character:1, Foreground:1, Background:1, Reserved:1)
|
||||
0x16FF
|
||||
-------
|
||||
0x1700 GENERIC SERIAL INTERFACE (64 Bytes)
|
||||
0x173F
|
||||
-------
|
||||
0x1740 RAM (59583 Bytes)
|
||||
0xFFFF
|
||||
|
||||
|
||||
|
||||
#==========================================================================================================================================
|
||||
# INTERRUPTS
|
||||
#==========================================================================================================================================
|
||||
BIOS Specific - Software Interrupts:
|
||||
====================================
|
||||
0x20: BIOS Interrupt (Uses R10 register for specific functionality)
|
||||
0x00: Set Interrupt Handler
|
||||
0x01: Clear Interrupt Handler
|
||||
0x10: Disk Interface
|
||||
0x11: Disk Interface - Get disk list
|
||||
0x12: Disk Interface - Load from DDD - BLOCKING
|
||||
0x30: BIOS Video Interrupt (Uses R10 register for specific functionality)
|
||||
0x01: Print Char in Text Single Mode (char stored in R9 register)
|
||||
0x02: New Line in Text Single Mode
|
||||
0x03: Print Null-Terminated String in Text Single Mode (string address stored in R9 register)
|
||||
0x04: Print Integer in Text Single Mode (integer stored in R9 register)
|
||||
0x05: Store Integer in buffer in Text Single Mode (integer stored in R9 register)
|
||||
0x06: Store character in buffer in Text Single Mode (integer stored in R9 register)
|
||||
0x07: Print buffer no flush in Text Single Mode
|
||||
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
|
||||
|
||||
0x21: Write VRAM in Text16 Colors Mode (Cell address stored in R9)
|
||||
0x22: Print String in Text16 Colors Mode (String address stored in R8, Cell address stored in R9)
|
||||
0x23: Print Integer in Text16 Colors Mode (Integer stored in R8, Cell address stored in R9)
|
||||
0x24: Clear Screen in Text16 Colors Mode (Cell address stored in R9)
|
||||
0x25: Scroll in Text16 Colors Mode
|
||||
|
||||
0xE0: Refresh Screen
|
||||
0xE1: Clear Screen
|
||||
|
||||
|
||||
Machine Specific - Hardware Interrupts:
|
||||
=======================================
|
||||
MAX INTERRUPT 0xAA
|
||||
0x80: Disk Interface Finished
|
||||
0xA0: Keyboard Interface - Key Pressed
|
||||
0xA1: Keyboard Interface - Key Released
|
||||
0xA2: Keyboard Interface - Text Entered
|
||||
0xE0: Virtual Display - Text16_Mode Screen Refreshed
|
||||
|
||||
|
||||
|
||||
#==========================================================================================================================================
|
||||
# DPT - Partition Table
|
||||
#==========================================================================================================================================
|
||||
|
||||
Disk Address: 0x200 - 0x400 (512 bytes)
|
||||
Header: (0x200 - 0x20B) (12 bytes)
|
||||
0x000: (2 bytes) - 0xF1CA - This number identifies this block as a DPT partition table
|
||||
0x002: (2 bytes) - DPT version
|
||||
0x004: (1 byte) - Partition count (max 5)
|
||||
0x005: (7 bytes) - Reserved
|
||||
Partition Table: (0x20C - 0x3FF) (500 bytes)
|
||||
Entry: (100 bytes) (x5)
|
||||
0x00: (4 bytes) - Start Address
|
||||
0x04: (4 bytes) - Size
|
||||
0x08: (2 bytes) - Flags
|
||||
0x08: (26 bytes) - Reserved
|
||||
0x24: (64 bytes) - Partition label
|
||||
|
||||
|
||||
|
||||
#==========================================================================================================================================
|
||||
# Regex
|
||||
#==========================================================================================================================================
|
||||
Type: Javascript
|
||||
|
||||
Number Constants
|
||||
0x[0-9A-Fa-f]+|0b[0-1]+|(?<!\w)[0-9]+(?!\w)
|
||||
|
||||
Labels
|
||||
\$\w+
|
||||
|
||||
Registers (case-insensitive)
|
||||
(?<!\w)(r[1-9]|r10|fl|pp|rv|fp|sp|ip|acc)(?!\w)
|
||||
|
||||
Variables in dasm
|
||||
VARIABLE_NAME(?!\.)(?!\w)
|
||||
|
||||
|
||||
|
||||
#==========================================================================================================================================
|
||||
# Test Disk DPT Block (4 MB Disk, 4 partitions)
|
||||
#==========================================================================================================================================
|
||||
F1 CA 00 02 04 FF FF FF FF FF FF FF
|
||||
|
||||
00 00 04 00
|
||||
00 00 14 00
|
||||
00 00
|
||||
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
||||
42 4F 4F 54 53 45 43 54 4F 52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
00 00 18 00
|
||||
00 01 68 00
|
||||
00 00
|
||||
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
00 01 80 00
|
||||
00 1F 40 00
|
||||
00 01
|
||||
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
||||
44 72 61 67 6F 6E 4F 53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
00 20 C0 00
|
||||
00 1F 40 00
|
||||
00 00
|
||||
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
||||
54 65 73 74 20 50 61 72 74 69 74 69 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
|
||||
Disk: 4096 kb
|
||||
=============
|
||||
boot + dpt 1 kb 1024 bytes (9x400) 0x0000.0000 -> 0x0000.03FF
|
||||
-------------
|
||||
boot-ssector 5 kb 5120 bytes (0x1400) 0x0000.0400 -> 0x0000.17FF
|
||||
Unallocated 90 kb 92160 bytes (0x16800) 0x0000.1800 -> 0x0001.7FFF
|
||||
DragonOS 2000 kb 2048000 bytes (0x1F4000) 0x0001.8000 -> 0x0020.BFFF
|
||||
Test Partition 2000 kb 2048000 bytes (0x1F4000) 0x0020.C000 -> 0x0040.0000
|
||||
|
||||
|
||||
|
||||
#==========================================================================================================================================
|
||||
# Bootstrap structure
|
||||
#==========================================================================================================================================
|
||||
Starting bytes of bootable partition:
|
||||
Identifier (2 Bytes) - Must be set to 0xF1C4
|
||||
Reserved (30 Bytes)
|
||||
|
||||
Kernel first stage block must start at PART_ADDR + 32 and must be 1024 bytes in size
|
||||
32
extra/info/todo.txt
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
Runtime:
|
||||
Add option to disable screenRedrawRate in debugger top-level prompt
|
||||
|
||||
Assembler:
|
||||
Add subroutine address export functionality
|
||||
|
||||
Bugs:
|
||||
|
||||
Refactor:
|
||||
Move all possible default values into data::DefaultValues class (in <GlobalData.hpp>)
|
||||
|
||||
External:
|
||||
Redo script to create windows Release
|
||||
|
||||
|
||||
|
||||
Done:
|
||||
*Fix VM closing when reaching hlt instruction
|
||||
*Add Struct export functionality
|
||||
*Add evaluation of direct struct instance name as as struct's first member
|
||||
*Add single Define export functionality
|
||||
*Inverted Colors in Text-Single-Color
|
||||
*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 "Extended mov" instruction set
|
||||
*Remove old offset mov
|
||||
*Implelemnt extmov mnemonics in dasm:
|
||||
*Update Ubuntu install instructions in readme file (for OmniaFramework aswell)
|
||||
*Add in place logic operators (and, or...) to ExtAlu CPU Extension
|
||||
*Implement native flags operators (set, zero, toggle)
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
printf "${green}\n============================================[ Building Application ]============================================\n\n${clear}"
|
||||
\cp -r ../extra/* ./
|
||||
if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
|
||||
make
|
||||
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
|
||||
mingw32-make.exe
|
||||
cp ../../omnia-framework/bin/libostd.dll ./
|
||||
fi
|
||||
printf "${green}\n=================================================================================================================\n\n"
|
||||
if [ $? -eq 0 ]; then
|
||||
cd scripts
|
||||
/bin/bash ./bios_flash
|
||||
/bin/bash ./load_mbr
|
||||
cd ..
|
||||
printf "${green}Compiling Test Program...\n"
|
||||
./dasm dss/handlerTest.dss -o handlerTest.bin --save-disassembly disassembly/handlerTest.dds
|
||||
printf "\n${green}Running Application...\n\n${clear}"
|
||||
./ddb config/testMachine.dvm --force-load handlerTest.bin 0x00 --verbose-load --track-step-diff --hide-vdisplay
|
||||
#./dvm config/testMachine.dvm --debug --force-load newTest.bin 0x00 --verbose-load
|
||||
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||
cp dragon/cmos.dr ../extra/dragon/cmos.dr
|
||||
fi
|
||||
24
extra/reload_env.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
green='\033[0;32m'
|
||||
clear='\033[0m'
|
||||
|
||||
printf "${green}Flashing BIOS...\n${clear}"
|
||||
./dasm dss/bios/entry.dss -o dragon/bios.bin -I dss $1
|
||||
|
||||
printf "\n${green}Compiling Drake...\n${clear}"
|
||||
printf "\n${green}1) loader.dss\n${clear}"
|
||||
./dasm dss/drake/loader.dss -o dragon/drake_loader.bin -I dss $1
|
||||
./dtools load-binary dragon/disk1.dr dragon/drake_loader.bin 0x00000000
|
||||
printf "\n${green}2) bootsector.dss\n${clear}"
|
||||
./dasm dss/drake/bootsector.dss -o dragon/drake_bootsector.bin -I dss $1
|
||||
./dtools load-binary dragon/disk1.dr dragon/drake_bootsector.bin 0x00000400
|
||||
|
||||
printf "\n${green}Compiling DragonOS...\n${clear}"
|
||||
printf "\n${green}1) kernel0.dss\n${clear}"
|
||||
./dasm dss/DragonOS/kernel0/kernel0.dss -o dragon/kernel0.bin -I dss --save-final-stage ./kernel0_final_stage.txt $1
|
||||
./dtools load-binary dragon/disk1.dr dragon/kernel0.bin 0x00018000
|
||||
|
||||
printf "\n"
|
||||
BIN
extra/res/Courier Prime.ttf
Normal file
BIN
extra/res/UbuntuMono-R.ttf
Normal file
|
|
@ -5,6 +5,6 @@ clear='\033[0m'
|
|||
|
||||
printf "${green}Reloading BIOS...\n${clear}"
|
||||
cd ..
|
||||
cp ../extra/dss/bios.dss ./dss/bios.dss
|
||||
./dasm dss/bios.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds
|
||||
cp ../extra/dss/bios/* ./dss/bios/
|
||||
./dasm dss/bios/entry.dss -o dragon/bios.bin -D
|
||||
cp dragon/bios.bin ../extra/dragon/bios.bin
|
||||
|
|
|
|||
18
extra/scripts/build_dragonos
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
|
||||
green='\033[0;32m'
|
||||
clear='\033[0m'
|
||||
|
||||
printf "\n${green}Compiling DragonOS...\n${clear}"
|
||||
cd ..
|
||||
cp -r ../extra/dss/DragonOS/* ./dss/DragonOS/
|
||||
|
||||
printf "\n${green}1) kernel0.dss\n${clear}"
|
||||
./dasm dss/DragonOS/kernel0/kernel0.dss -o dragon/kernel0.bin -D --verbose
|
||||
./dtools load-binary dragon/disk1.dr dragon/kernel0.bin 0x00018000
|
||||
|
||||
printf "\n"
|
||||
|
||||
|
||||
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||
# rm dragon/kernel0.bin
|
||||
23
extra/scripts/build_drake
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
green='\033[0;32m'
|
||||
clear='\033[0m'
|
||||
|
||||
printf "\n${green}Compiling Drake...\n${clear}"
|
||||
cd ..
|
||||
cp ../extra/dss/drake/* ./dss/drake/
|
||||
|
||||
printf "\n${green}1) loader.dss\n${clear}"
|
||||
./dasm dss/drake/loader.dss -o dragon/drake_loader.bin -D
|
||||
./dtools load-binary dragon/disk1.dr dragon/drake_loader.bin 0x00000000
|
||||
|
||||
printf "\n${green}2) bootsector.dss\n${clear}"
|
||||
./dasm dss/drake/bootsector.dss -o dragon/drake_bootsector.bin -D
|
||||
./dtools load-binary dragon/disk1.dr dragon/drake_bootsector.bin 0x00000400
|
||||
|
||||
printf "\n"
|
||||
|
||||
|
||||
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||
rm dragon/drake_loader.bin
|
||||
rm dragon/drake_bootsector.bin
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
green='\033[0;32m'
|
||||
clear='\033[0m'
|
||||
|
||||
printf "\n${green}Reloading MBR Block...\n${clear}"
|
||||
cd ..
|
||||
cp ../extra/dss/mbr.dss ./dss/mbr.dss
|
||||
./dasm dss/mbr.dss -o dragon/mbr.bin --save-disassembly disassembly/mbr.dds
|
||||
./dtools load-program dragon/disk1.dr dragon/mbr.bin 0x00000000
|
||||
printf "\n"
|
||||
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||
rm dragon/mbr.bin
|
||||
320
licences/libgcc-LICENCE.txt
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
The GNU General Public License is a free, copyleft license for software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
0. Definitions.
|
||||
“This License” refers to version 3 of the GNU General Public License.
|
||||
|
||||
“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
|
||||
|
||||
“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
|
||||
|
||||
To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
|
||||
|
||||
A “covered work” means either the unmodified Program or a work based on the Program.
|
||||
|
||||
To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
|
||||
|
||||
To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
|
||||
|
||||
A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
|
||||
|
||||
The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
|
||||
b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
|
||||
c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
|
||||
d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
|
||||
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
|
||||
b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
|
||||
c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
|
||||
d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
|
||||
e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
|
||||
A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
|
||||
|
||||
A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
|
||||
|
||||
“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
|
||||
b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
|
||||
c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
|
||||
d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
|
||||
e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
|
||||
f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
|
||||
All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
|
||||
|
||||
An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
|
||||
|
||||
A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
|
||||
|
||||
A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
License
|
||||
There are two licenses affecting GNU libstdc++: one for the code, and one for the documentation.
|
||||
|
||||
There is a license section in the FAQ regarding common questions. If you have more questions, ask the FSF or the gcc mailing list.
|
||||
|
||||
The Code: GPL
|
||||
The source code is distributed under the GNU General Public License version 3, with the addition under section 7 of an exception described in the “GCC Runtime Library Exception, version 3.1” as follows (or see the file COPYING.RUNTIME):
|
||||
|
||||
|
||||
GCC RUNTIME LIBRARY EXCEPTION
|
||||
|
||||
Version 3.1, 31 March 2009
|
||||
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
This GCC Runtime Library Exception ("Exception") is an additional
|
||||
permission under section 7 of the GNU General Public License, version
|
||||
3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
|
||||
bears a notice placed by the copyright holder of the file stating that
|
||||
the file is governed by GPLv3 along with this Exception.
|
||||
|
||||
When you use GCC to compile a program, GCC may combine portions of
|
||||
certain GCC header files and runtime libraries with the compiled
|
||||
program. The purpose of this Exception is to allow compilation of
|
||||
non-GPL (including proprietary) programs to use, in this way, the
|
||||
header files and runtime libraries covered by this Exception.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
A file is an "Independent Module" if it either requires the Runtime
|
||||
Library for execution after a Compilation Process, or makes use of an
|
||||
interface provided by the Runtime Library, but is not otherwise based
|
||||
on the Runtime Library.
|
||||
|
||||
"GCC" means a version of the GNU Compiler Collection, with or without
|
||||
modifications, governed by version 3 (or a specified later version) of
|
||||
the GNU General Public License (GPL) with the option of using any
|
||||
subsequent versions published by the FSF.
|
||||
|
||||
"GPL-compatible Software" is software whose conditions of propagation,
|
||||
modification and use would permit combination with GCC in accord with
|
||||
the license of GCC.
|
||||
|
||||
"Target Code" refers to output from any compiler for a real or virtual
|
||||
target processor architecture, in executable form or suitable for
|
||||
input to an assembler, loader, linker and/or execution
|
||||
phase. Notwithstanding that, Target Code does not include data in any
|
||||
format that is used as a compiler intermediate representation, or used
|
||||
for producing a compiler intermediate representation.
|
||||
|
||||
The "Compilation Process" transforms code entirely represented in
|
||||
non-intermediate languages designed for human-written code, and/or in
|
||||
Java Virtual Machine byte code, into Target Code. Thus, for example,
|
||||
use of source code generators and preprocessors need not be considered
|
||||
part of the Compilation Process, since the Compilation Process can be
|
||||
understood as starting with the output of the generators or
|
||||
preprocessors.
|
||||
|
||||
A Compilation Process is "Eligible" if it is done using GCC, alone or
|
||||
with other GPL-compatible software, or if it is done without using any
|
||||
work based on GCC. For example, using non-GPL-compatible Software to
|
||||
optimize any GCC intermediate representations would not qualify as an
|
||||
Eligible Compilation Process.
|
||||
|
||||
1. Grant of Additional Permission.
|
||||
|
||||
You have permission to propagate a work of Target Code formed by
|
||||
combining the Runtime Library with Independent Modules, even if such
|
||||
propagation would otherwise violate the terms of GPLv3, provided that
|
||||
all Target Code was generated by Eligible Compilation Processes. You
|
||||
may then convey such a combination under terms of your choice,
|
||||
consistent with the licensing of the Independent Modules.
|
||||
|
||||
2. No Weakening of GCC Copyleft.
|
||||
|
||||
The availability of this Exception does not imply any general
|
||||
presumption that third-party software is unaffected by the copyleft
|
||||
requirements of the license of GCC.
|
||||
|
||||
|
||||
Hopefully that text is self-explanatory. If it isn't, you need to speak to your lawyer, or the Free Software Foundation.
|
||||
|
||||
The Documentation: GPL, FDL
|
||||
The documentation shipped with the library and made available over the web, excluding the pages generated from source comments, are copyrighted by the Free Software Foundation, and placed under the GNU Free Documentation License version 1.3. There are no Front-Cover Texts, no Back-Cover Texts, and no Invariant Sections.
|
||||
|
||||
For documentation generated by doxygen or other automated tools via processing source code comments and markup, the original source code license applies to the generated files. Thus, the doxygen documents are licensed GPL.
|
||||
|
||||
If you plan on making copies of the documentation, please let us know. We can probably offer suggestions.
|
||||
320
licences/libstdc++-LICENCE.txt
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
The GNU General Public License is a free, copyleft license for software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
0. Definitions.
|
||||
“This License” refers to version 3 of the GNU General Public License.
|
||||
|
||||
“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
|
||||
|
||||
“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
|
||||
|
||||
To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
|
||||
|
||||
A “covered work” means either the unmodified Program or a work based on the Program.
|
||||
|
||||
To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
|
||||
|
||||
To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
|
||||
|
||||
A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
|
||||
|
||||
The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
|
||||
b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
|
||||
c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
|
||||
d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
|
||||
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
|
||||
b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
|
||||
c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
|
||||
d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
|
||||
e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
|
||||
A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
|
||||
|
||||
A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
|
||||
|
||||
“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
|
||||
b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
|
||||
c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
|
||||
d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
|
||||
e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
|
||||
f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
|
||||
All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
|
||||
|
||||
An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
|
||||
|
||||
A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
|
||||
|
||||
A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
License
|
||||
There are two licenses affecting GNU libstdc++: one for the code, and one for the documentation.
|
||||
|
||||
There is a license section in the FAQ regarding common questions. If you have more questions, ask the FSF or the gcc mailing list.
|
||||
|
||||
The Code: GPL
|
||||
The source code is distributed under the GNU General Public License version 3, with the addition under section 7 of an exception described in the “GCC Runtime Library Exception, version 3.1” as follows (or see the file COPYING.RUNTIME):
|
||||
|
||||
|
||||
GCC RUNTIME LIBRARY EXCEPTION
|
||||
|
||||
Version 3.1, 31 March 2009
|
||||
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
This GCC Runtime Library Exception ("Exception") is an additional
|
||||
permission under section 7 of the GNU General Public License, version
|
||||
3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
|
||||
bears a notice placed by the copyright holder of the file stating that
|
||||
the file is governed by GPLv3 along with this Exception.
|
||||
|
||||
When you use GCC to compile a program, GCC may combine portions of
|
||||
certain GCC header files and runtime libraries with the compiled
|
||||
program. The purpose of this Exception is to allow compilation of
|
||||
non-GPL (including proprietary) programs to use, in this way, the
|
||||
header files and runtime libraries covered by this Exception.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
A file is an "Independent Module" if it either requires the Runtime
|
||||
Library for execution after a Compilation Process, or makes use of an
|
||||
interface provided by the Runtime Library, but is not otherwise based
|
||||
on the Runtime Library.
|
||||
|
||||
"GCC" means a version of the GNU Compiler Collection, with or without
|
||||
modifications, governed by version 3 (or a specified later version) of
|
||||
the GNU General Public License (GPL) with the option of using any
|
||||
subsequent versions published by the FSF.
|
||||
|
||||
"GPL-compatible Software" is software whose conditions of propagation,
|
||||
modification and use would permit combination with GCC in accord with
|
||||
the license of GCC.
|
||||
|
||||
"Target Code" refers to output from any compiler for a real or virtual
|
||||
target processor architecture, in executable form or suitable for
|
||||
input to an assembler, loader, linker and/or execution
|
||||
phase. Notwithstanding that, Target Code does not include data in any
|
||||
format that is used as a compiler intermediate representation, or used
|
||||
for producing a compiler intermediate representation.
|
||||
|
||||
The "Compilation Process" transforms code entirely represented in
|
||||
non-intermediate languages designed for human-written code, and/or in
|
||||
Java Virtual Machine byte code, into Target Code. Thus, for example,
|
||||
use of source code generators and preprocessors need not be considered
|
||||
part of the Compilation Process, since the Compilation Process can be
|
||||
understood as starting with the output of the generators or
|
||||
preprocessors.
|
||||
|
||||
A Compilation Process is "Eligible" if it is done using GCC, alone or
|
||||
with other GPL-compatible software, or if it is done without using any
|
||||
work based on GCC. For example, using non-GPL-compatible Software to
|
||||
optimize any GCC intermediate representations would not qualify as an
|
||||
Eligible Compilation Process.
|
||||
|
||||
1. Grant of Additional Permission.
|
||||
|
||||
You have permission to propagate a work of Target Code formed by
|
||||
combining the Runtime Library with Independent Modules, even if such
|
||||
propagation would otherwise violate the terms of GPLv3, provided that
|
||||
all Target Code was generated by Eligible Compilation Processes. You
|
||||
may then convey such a combination under terms of your choice,
|
||||
consistent with the licensing of the Independent Modules.
|
||||
|
||||
2. No Weakening of GCC Copyleft.
|
||||
|
||||
The availability of this Exception does not imply any general
|
||||
presumption that third-party software is unaffected by the copyleft
|
||||
requirements of the license of GCC.
|
||||
|
||||
|
||||
Hopefully that text is self-explanatory. If it isn't, you need to speak to your lawyer, or the Free Software Foundation.
|
||||
|
||||
The Documentation: GPL, FDL
|
||||
The documentation shipped with the library and made available over the web, excluding the pages generated from source comments, are copyrighted by the Free Software Foundation, and placed under the GNU Free Documentation License version 1.3. There are no Front-Cover Texts, no Back-Cover Texts, and no Invariant Sections.
|
||||
|
||||
For documentation generated by doxygen or other automated tools via processing source code comments and markup, the original source code license applies to the generated files. Thus, the doxygen documents are licensed GPL.
|
||||
|
||||
If you plan on making copies of the documentation, please let us know. We can probably offer suggestions.
|
||||
5
licences/libwinpthread-LICENCE.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
1
other/build.nr
Normal file
|
|
@ -0,0 +1 @@
|
|||
1650
|
||||
80
other/build_dependencies.sh
Executable file
|
|
@ -0,0 +1,80 @@
|
|||
#!/bin/bash
|
||||
|
||||
detect_package_manager() {
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
source /etc/os-release
|
||||
case "$ID" in
|
||||
arch|manjaro|endeavouros|garuda|cachyos)
|
||||
echo "pacman"
|
||||
;;
|
||||
ubuntu|debian|linuxmint)
|
||||
echo "apt"
|
||||
;;
|
||||
fedora)
|
||||
echo "dnf"
|
||||
;;
|
||||
*)
|
||||
echo "unsupported"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo "unsupported"
|
||||
fi
|
||||
}
|
||||
|
||||
install_manual_dependencies_linux() {
|
||||
# Build OmniaFramework
|
||||
git clone https://github.com/OmniaX-dev/OmniaFramework.git
|
||||
cd OmniaFramework
|
||||
./build release
|
||||
./build install
|
||||
cd ../..
|
||||
}
|
||||
|
||||
set -e
|
||||
mkdir ../dependencies && cd ../dependencies
|
||||
|
||||
if [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
|
||||
# Setup environment
|
||||
pacman -Syuu --noconfirm
|
||||
pacman -S --noconfirm --needed base-devel mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-gdb \
|
||||
mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-make mingw-w64-ucrt-x86_64-boost \
|
||||
mingw-w64-ucrt-x86_64-glm mingw-w64-ucrt-x86_64-SDL2 mingw-w64-ucrt-x86_64-SDL2_mixer \
|
||||
mingw-w64-ucrt-x86_64-SDL2_image mingw-w64-ucrt-x86_64-SDL2_ttf mingw-w64-ucrt-x86_64-SDL2_gfx \
|
||||
|
||||
# Build OmniaFramework
|
||||
pacman -S --noconfirm --needed base-devel mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-gdb \
|
||||
mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-make \
|
||||
mingw-w64-ucrt-x86_64-boost mingw-w64-ucrt-x86_64-SDL2 \
|
||||
mingw-w64-ucrt-x86_64-SDL2_mixer mingw-w64-ucrt-x86_64-SDL2_image \
|
||||
mingw-w64-ucrt-x86_64-SDL2_ttf mingw-w64-ucrt-x86_64-SDL2_gfx
|
||||
|
||||
|
||||
git clone https://github.com/OmniaX-dev/OmniaFramework.git
|
||||
cd OmniaFramework
|
||||
./build release
|
||||
./build install
|
||||
cd ../..
|
||||
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
|
||||
pkgmgr=$(detect_package_manager)
|
||||
case "$pkgmgr" in
|
||||
pacman) # Arch Based ==================================================================================================
|
||||
sudo pacman -Syu --noconfirm
|
||||
sudo pacman -S --noconfirm --needed base-devel clang openssl gdb cmake make boost sdl2 sdl2_mixer sdl2_image sdl2_ttf sdl2_gfx
|
||||
;;
|
||||
apt) # Debian Based ==================================================================================================
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential dkms linux-headers-$(uname -r) clang gdb make cmake libssl-dev libboost-all-dev libsdl2-dev \
|
||||
libsdl2-mixer-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-gfx-dev libxcb-randr0-dev
|
||||
;;
|
||||
dnf) # Fedora ==================================================================================================
|
||||
sudo dnf install -y gcc gcc-c++ make clang gdb cmake clang-tools-extra boost boost-devel openssl openssl-devel SDL2 SDL2_image \
|
||||
SDL2_mixer SDL2_ttf SDL2_gfx SDL2-devel SDL2_image-devel SDL2_mixer-devel SDL2_ttf-devel SDL2_gfx-devel
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported distro. Supported distros are: Arch, EndeavourOS, Garuda, Manjaro, Ubuntu, Mint, Debian, Fedora."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
install_manual_dependencies_linux
|
||||
fi
|
||||
20
other/build_linux_release.sh
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd ..
|
||||
./build release
|
||||
|
||||
printf "\n\n\033[0;32mBuilding Linux release...\n\033[0m"
|
||||
|
||||
mkdir bin/DragonVM_linux64
|
||||
|
||||
cp -r extra/* bin/DragonVM_linux64/
|
||||
cp bin/dvm bin/DragonVM_linux64
|
||||
cp bin/ddb bin/DragonVM_linux64
|
||||
cp bin/dasm bin/DragonVM_linux64
|
||||
cp bin/dtools bin/DragonVM_linux64
|
||||
|
||||
|
||||
cp -r licences bin/DragonVM_linux64
|
||||
cp LICENSE bin/DragonVM_linux64/licences/DragonVM-LICENCE.txt
|
||||
|
||||
printf "\n\033[0;32mLinux release ready in bin/DragonVM_linux64!\n\033[0m"
|
||||
33
other/build_windows_release.sh
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/bash
|
||||
|
||||
MSYS2_ROOT=c:/msys64
|
||||
|
||||
cd ..
|
||||
./build release
|
||||
|
||||
printf "\n\n\033[0;32mBuilding Windows release...\n\033[0m"
|
||||
|
||||
mkdir bin/DragonVM_w64
|
||||
|
||||
cp -r extra/* bin/DragonVM_w64/
|
||||
cp other/dvm_appIcon.ico bin/DragonVM_w64
|
||||
cp other/ddb_appIcon.ico bin/DragonVM_w64
|
||||
cp other/dtools_appIcon.ico bin/DragonVM_w64
|
||||
cp other/dasm_appIcon.ico bin/DragonVM_w64
|
||||
|
||||
cp bin/dvm.exe bin/DragonVM_w64
|
||||
cp bin/ddb.exe bin/DragonVM_w64
|
||||
cp bin/dasm.exe bin/DragonVM_w64
|
||||
cp bin/dtools.exe bin/DragonVM_w64
|
||||
|
||||
for dll in libgcc_s_seh-1.dll libstdc++-6.dll libostd.dll libwinpthread-1.dll \
|
||||
SDL2.dll SDL2_image.dll; do
|
||||
src="$MSYS2_ROOT/ucrt64/bin/$dll"
|
||||
[[ -f "$src" ]] || { echo "Missing: $dll"; exit 1; }
|
||||
cp "$src" bin/DragonVM_w64/
|
||||
done
|
||||
|
||||
cp -r licences bin/DragonVM_w64
|
||||
cp LICENSE bin/DragonVM_w64/licences/DragonVM-LICENCE.txt
|
||||
|
||||
printf "\n\033[0;32mWindows release ready in bin/DragonVM_w64!\n\033[0m"
|
||||
BIN
other/dasm_appIcon.ico
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
1
other/dasm_appIcon.rc
Normal file
|
|
@ -0,0 +1 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "dasm_appIcon.ico"
|
||||
BIN
other/ddb_appIcon.ico
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
1
other/ddb_appIcon.rc
Normal file
|
|
@ -0,0 +1 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "ddb_appIcon.ico"
|
||||
BIN
other/dtools_appIcon.ico
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
1
other/dtools_appIcon.rc
Normal file
|
|
@ -0,0 +1 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "dtools_appIcon.ico"
|
||||
BIN
other/dvm_appIcon.ico
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
1
other/dvm_appIcon.rc
Normal file
|
|
@ -0,0 +1 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "dvm_appIcon.ico"
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <ostd/io/IOHandlers.hpp>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
|
|
@ -11,23 +12,68 @@ namespace dragon
|
|||
}
|
||||
namespace code
|
||||
{
|
||||
class IncludePreprocessor
|
||||
{
|
||||
public:
|
||||
static std::vector<String> loadEntryFile(const String& filePath);
|
||||
|
||||
private:
|
||||
static bool __can_file_be_included(std::vector<String>& lines);
|
||||
static bool __include_loop(void);
|
||||
static std::vector<String> __load_file(const String& filePath);
|
||||
|
||||
private:
|
||||
inline static std::vector<String> m_lines;
|
||||
inline static std::vector<String> m_guards;
|
||||
inline static String m_directory { "" };
|
||||
};
|
||||
|
||||
class Assembler
|
||||
{
|
||||
public: struct tDisassemblyLine {
|
||||
uint32_t addr = 0;
|
||||
ostd::String code = "";
|
||||
public: struct tDefine
|
||||
{
|
||||
String name;
|
||||
String value;
|
||||
};
|
||||
public: struct tDisassemblyLine
|
||||
{
|
||||
u32 addr = 0;
|
||||
String code = "";
|
||||
u16 size = 1;
|
||||
inline bool operator<(const tDisassemblyLine& second) const { return addr < second.addr; }
|
||||
inline bool operator>(const tDisassemblyLine& second) const { return addr > second.addr; }
|
||||
};
|
||||
public: struct tSymbol
|
||||
{
|
||||
std::vector<ostd::UByte> bytes;
|
||||
uint16_t address { 0 };
|
||||
u16 address { 0 };
|
||||
};
|
||||
public: struct tLabel
|
||||
{
|
||||
std::vector<uint16_t> references;
|
||||
uint16_t address { 0 };
|
||||
std::vector<u16> references;
|
||||
u16 address { 0 };
|
||||
};
|
||||
public: enum class eOperandType {
|
||||
public: struct tStructMember
|
||||
{
|
||||
String name;
|
||||
std::vector<u8> data;
|
||||
i32 position;
|
||||
inline bool operator<(const tStructMember& second) const { return position < second.position; }
|
||||
inline bool operator>(const tStructMember& second) const { return position > second.position; }
|
||||
};
|
||||
public: struct tStructDefinition
|
||||
{
|
||||
String name;
|
||||
std::vector<tStructMember> members;
|
||||
i32 size;
|
||||
};
|
||||
public: struct tExportSpec
|
||||
{
|
||||
String fileName { "" };
|
||||
std::vector<String> lines;
|
||||
};
|
||||
public: enum class eOperandType
|
||||
{
|
||||
Register = 0,
|
||||
Immediate,
|
||||
DerefMemory,
|
||||
|
|
@ -37,49 +83,105 @@ namespace dragon
|
|||
Error
|
||||
};
|
||||
|
||||
public:
|
||||
static ostd::ByteStream assembleFromFile(ostd::String fileName);
|
||||
static void loadSource(ostd::String source);
|
||||
static ostd::ByteStream assembleToFile(ostd::String sourceFileName, ostd::String binaryFileName);
|
||||
static ostd::ByteStream assembleToVirtualDisk(ostd::String fileName, hw::VirtualHardDrive& vhdd, uint32_t address);
|
||||
static bool saveDisassemblyToFile(ostd::String fileName);
|
||||
public: class Application
|
||||
{
|
||||
public: struct tCommandLineArgs
|
||||
{
|
||||
inline tCommandLineArgs(void) { }
|
||||
String source_file_path { "" };
|
||||
String dest_file_path { "" };
|
||||
bool save_disassembly { false };
|
||||
i32 verbose_level { 0xFF };
|
||||
bool debug_mode { false };
|
||||
bool save_exports { true };
|
||||
String disassembly_file_path { "" };
|
||||
String final_stage_path { "" };
|
||||
std::vector<String> cpu_extensions;
|
||||
std::vector<String> include_directories;
|
||||
};
|
||||
|
||||
static void tempPrint(void);
|
||||
public:
|
||||
static i32 loadArguments(int argc, char** argv);
|
||||
static void print_application_help(void);
|
||||
|
||||
public:
|
||||
inline static tCommandLineArgs args;
|
||||
inline static const i32 RETURN_VAL_EXIT_SUCCESS = 0;
|
||||
inline static const i32 RETURN_VAL_CLOSE_PROGRAM = 512;
|
||||
inline static const i32 RETURN_VAL_TOO_FEW_ARGUMENTS = 1;
|
||||
inline static const i32 RETURN_VAL_MISSING_PARAM = 2;
|
||||
inline static const i32 RETURN_VAL_INVALID_PARAM = 3;
|
||||
};
|
||||
|
||||
public:
|
||||
static ostd::ByteStream assembleFromFile(String fileName);
|
||||
static ostd::ByteStream assembleToFile(String sourceFileName, String binaryFileName);
|
||||
static ostd::ByteStream assembleToVirtualDisk(String fileName, hw::VirtualHardDrive& vhdd, u32 address);
|
||||
static bool saveDisassemblyToFile(String fileName);
|
||||
static void printProgramInfo(i32 verbose_level = 1);
|
||||
|
||||
private:
|
||||
static void insertHeader(void);
|
||||
|
||||
static void removeComments(void);
|
||||
static void replaceDefines(void);
|
||||
static void replaceGroupDefines(void);
|
||||
static void parseStructures(void);
|
||||
static void parseStructInstances(void);
|
||||
|
||||
static void parseExportSpecifications(void);
|
||||
static void createExports(void);
|
||||
static void replaceExportBuiltinVars(void);
|
||||
static void createExportFiles(void);
|
||||
static void saveCurrentStageToFile(void);
|
||||
|
||||
static void parseSections(void);
|
||||
static void parseDataSection(void);
|
||||
static void parseCodeSection(void);
|
||||
static void parseDebugOperands(ostd::String line);
|
||||
static void parse0Operand(ostd::String line);
|
||||
static void parse1Operand(ostd::String line);
|
||||
static void parse2Operand(ostd::String line);
|
||||
static void parse3Operand(ostd::String line);
|
||||
|
||||
static void parseDebugOperands(String line);
|
||||
static void parse0Operand(String line);
|
||||
static void parse1Operand(String line);
|
||||
static void parse2Operand(String line);
|
||||
static void parse3Operand(String line);
|
||||
static void combineDataAndCode(void);
|
||||
|
||||
static ostd::String replaceSymbols(ostd::String line);
|
||||
static String replaceSymbols(String line);
|
||||
static void replaceLabelRefs(void);
|
||||
static eOperandType parseOperand(ostd::String op, int16_t& outOp);
|
||||
static uint8_t parseRegister(ostd::String op);
|
||||
static eOperandType parseOperand(String op, i16& outOp);
|
||||
static u8 parseRegister(String op);
|
||||
|
||||
private:
|
||||
inline static ostd::String m_rawSource { "" };
|
||||
inline static String m_rawSource { "" };
|
||||
inline static ostd::ByteStream m_code;
|
||||
inline static std::vector<ostd::String> m_lines;
|
||||
inline static std::vector<ostd::String> m_rawDataSection;
|
||||
inline static std::vector<ostd::String> m_rawCodeSection;
|
||||
inline static std::unordered_map<ostd::String, tSymbol> m_symbolTable;
|
||||
inline static std::unordered_map<ostd::String, tLabel> m_labelTable;
|
||||
inline static uint16_t m_fixedSize { 0 };
|
||||
inline static uint8_t m_fixedFillValue { 0x00 };
|
||||
inline static uint16_t m_loadAddress { 0x0000 };
|
||||
inline static uint16_t m_currentDataAddr { 0x0000 };
|
||||
inline static uint16_t m_dataSize { 0x0000 };
|
||||
inline static uint16_t m_programSize { 0x0000 };
|
||||
|
||||
inline static std::vector<String> m_lines;
|
||||
inline static std::vector<String> m_rawDataSection;
|
||||
inline static std::vector<String> m_rawCodeSection;
|
||||
|
||||
inline static std::unordered_map<String, tSymbol> m_symbolTable;
|
||||
inline static std::unordered_map<String, tLabel> m_labelTable;
|
||||
|
||||
inline static u16 m_fixedSize { 0 };
|
||||
inline static u8 m_fixedFillValue { 0x00 };
|
||||
inline static u16 m_loadAddress { 0x0000 };
|
||||
inline static u16 m_currentDataAddr { 0x0000 };
|
||||
inline static u16 m_dataSize { 0x0000 };
|
||||
inline static u16 m_programSize { 0x0000 };
|
||||
inline static String m_entry_lbl { "" };
|
||||
inline static String m_headerStr { "" };
|
||||
|
||||
inline static std::vector<tStructDefinition> m_structDefs;
|
||||
inline static std::vector<tDisassemblyLine> m_disassembly;
|
||||
|
||||
inline static std::unordered_map<String, tExportSpec> m_exports;
|
||||
|
||||
inline static ostd::ConsoleOutputHandler out;
|
||||
|
||||
public:
|
||||
inline static bool saveExports { false };
|
||||
inline static bool debugMode { false };
|
||||
inline static std::vector<String> cpuExtensions;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
153
src/assembler/DASMApp.cpp
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
#include "Assembler.hpp"
|
||||
#include <ostd/math/Random.hpp>
|
||||
#include <ostd/io/FileSystem.hpp>
|
||||
#include <ostd/utils/Hash.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace code
|
||||
{
|
||||
i32 Assembler::Application::loadArguments(int argc, char** argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
out.fg(ostd::ConsoleColors::Red).p("Error: too few arguments.").nl();
|
||||
out.fg(ostd::ConsoleColors::Red).p("Use the --help option for more info.").reset().nl();
|
||||
return RETURN_VAL_TOO_FEW_ARGUMENTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.source_file_path = argv[1];
|
||||
if (args.source_file_path == "--help")
|
||||
{
|
||||
print_application_help();
|
||||
return RETURN_VAL_CLOSE_PROGRAM;
|
||||
}
|
||||
args.disassembly_file_path = "";
|
||||
bool disable_extmov = false;
|
||||
bool disable_extalu = false;
|
||||
args.verbose_level = -1;
|
||||
for (i32 i = 2; i < argc; i++)
|
||||
{
|
||||
String edit(argv[i]);
|
||||
if (edit == "-o")
|
||||
{
|
||||
if (i == argc - 1)
|
||||
return RETURN_VAL_MISSING_PARAM;
|
||||
i++;
|
||||
args.dest_file_path = argv[i];
|
||||
}
|
||||
else if (edit == "-I" || edit == "--include-path")
|
||||
{
|
||||
if (i == argc - 1)
|
||||
return RETURN_VAL_MISSING_PARAM;
|
||||
i++;
|
||||
String _include = argv[i];
|
||||
_include.trim();
|
||||
if (!_include.endsWith("/"))
|
||||
_include.add("/");
|
||||
if (!ostd::FileSystem::directoryExists(_include))
|
||||
return RETURN_VAL_INVALID_PARAM;
|
||||
args.include_directories.push_back(_include);
|
||||
}
|
||||
else if (edit == "--save-disassembly")
|
||||
{
|
||||
if (i == argc - 1)
|
||||
return RETURN_VAL_MISSING_PARAM;
|
||||
i++;
|
||||
args.disassembly_file_path = argv[i];
|
||||
args.save_disassembly = true;
|
||||
}
|
||||
else if (edit == "--save-final-stage")
|
||||
{
|
||||
if (i == argc - 1)
|
||||
return RETURN_VAL_MISSING_PARAM;
|
||||
i++;
|
||||
String final_path = argv[i];
|
||||
if (!ostd::FileSystem::ensureFile(final_path))
|
||||
return RETURN_VAL_INVALID_PARAM;
|
||||
args.final_stage_path = final_path;
|
||||
}
|
||||
else if (edit == "--help")
|
||||
{
|
||||
print_application_help();
|
||||
return RETURN_VAL_CLOSE_PROGRAM;
|
||||
}
|
||||
else if (edit == "-D" || edit == "--debug")
|
||||
args.debug_mode = true;
|
||||
else if (edit == "--disable-extmov")
|
||||
disable_extmov = true;
|
||||
else if (edit == "--disable-extalu")
|
||||
disable_extalu = true;
|
||||
else if (edit == "--verbose")
|
||||
args.verbose_level = 1;
|
||||
else if (edit == "--verbose-2")
|
||||
args.verbose_level = 2;
|
||||
else if (edit == "--verbose-full")
|
||||
args.verbose_level = 0;
|
||||
else if (edit == "--disable-exports")
|
||||
args.save_exports = false;
|
||||
}
|
||||
if (args.debug_mode)
|
||||
{
|
||||
if (args.verbose_level == -1)
|
||||
args.verbose_level = 1;
|
||||
args.save_disassembly = true;
|
||||
}
|
||||
if (!disable_extalu)
|
||||
args.cpu_extensions.push_back("extalu");
|
||||
if (!disable_extmov)
|
||||
args.cpu_extensions.push_back("extmov");
|
||||
if (args.save_disassembly && args.disassembly_file_path == "")
|
||||
args.disassembly_file_path = "disassembly/" + ostd::Hash::md5(args.dest_file_path) + ".dds";
|
||||
}
|
||||
return RETURN_VAL_EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void Assembler::Application::print_application_help(void)
|
||||
{
|
||||
i32 commandLength = 46;
|
||||
|
||||
out.nl().fg(ostd::ConsoleColors::Yellow).p("List of available parameters:").reset().nl();
|
||||
String tmpCommand = "--save-disassembly <destination-directory>";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Saves debug information in the destination directory. (Enabled by default in debug mode.)").reset().nl();
|
||||
tmpCommand = "--save-final-stage <destination-file>";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Saves the final full stripped code to the specified file.").reset().nl();
|
||||
tmpCommand = "--verbose";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Shows more information about the assembled program.").reset().nl();
|
||||
tmpCommand = "--verbose-2";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Shows more information about the assembled program. (Structures/Symbols)").reset().nl();
|
||||
tmpCommand = "--verbose-full";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Enables all levels of verbose.").reset().nl();
|
||||
tmpCommand = "-o <destination-binary-file>";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to specify the output binary file.").reset().nl();
|
||||
tmpCommand = "--disable-exports";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to disable any specified exports in the code.").reset().nl();
|
||||
tmpCommand = "--disable-extmov";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Disables mnemonics for the <extmov> CPU extension.").reset().nl();
|
||||
tmpCommand = "--disable-extalu";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Disables mnemonics for the <extalu> CPU extension.").reset().nl();
|
||||
tmpCommand = "--debug, -D";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to enable debug mode.").reset().nl();
|
||||
tmpCommand = "--include-path, -I <include-directory-path>";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used specify an include directory path (absolute or relative to the <dasm> executable location).").reset().nl();
|
||||
tmpCommand = "--help";
|
||||
tmpCommand.addRightPadding(commandLength);
|
||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Displays this help message.").reset().nl();
|
||||
|
||||
out.nl().fg(ostd::ConsoleColors::Magenta).p("Usage: ./dasm <source> -o <destination> [...options...]").reset().nl();
|
||||
out.nl();
|
||||
}
|
||||
}
|
||||
}
|
||||
118
src/assembler/IncludePreprocessor.cpp
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
#include "Assembler.hpp"
|
||||
|
||||
#include <ostd/io/File.hpp>
|
||||
#include <ostd/io/FileSystem.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace code
|
||||
{
|
||||
std::vector<String> IncludePreprocessor::loadEntryFile(const String& filePath)
|
||||
{
|
||||
m_guards.clear();
|
||||
m_lines.clear();
|
||||
m_directory = "";
|
||||
m_lines = __load_file(filePath);
|
||||
|
||||
if (m_lines.size() == 0) return { }; //TODO: Error
|
||||
if (filePath.contains("/"))
|
||||
m_directory = filePath.new_substr(0, filePath.lastIndexOf("/") + 1);
|
||||
if (!__can_file_be_included(m_lines))
|
||||
return { }; //TODO: Error
|
||||
if (!__include_loop()) return { }; //TODO: Error
|
||||
std::vector<String> newLines;
|
||||
for (auto& line : m_lines)
|
||||
{
|
||||
String lineEdit = line.new_trim();
|
||||
if (lineEdit != "")
|
||||
newLines.push_back(line);
|
||||
}
|
||||
m_lines.clear();
|
||||
m_lines = newLines;
|
||||
return m_lines;
|
||||
}
|
||||
|
||||
bool IncludePreprocessor::__can_file_be_included(std::vector<String>& lines)
|
||||
{
|
||||
String guard_name = "";
|
||||
for (auto& line : lines)
|
||||
{
|
||||
String lineEdit = line.new_trim();
|
||||
if (lineEdit.new_toLower().startsWith("@guard "))
|
||||
{
|
||||
guard_name = lineEdit.new_substr(7).trim();
|
||||
line = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (guard_name == "") return true;
|
||||
for (auto& guard : m_guards)
|
||||
{
|
||||
if (guard == guard_name)
|
||||
return false;
|
||||
}
|
||||
m_guards.push_back(guard_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncludePreprocessor::__include_loop(void)
|
||||
{
|
||||
std::vector<String> lines = m_lines;
|
||||
bool included = false;
|
||||
do
|
||||
{
|
||||
included = false;
|
||||
u32 i = 0;
|
||||
for ( ; i < lines.size(); i++)
|
||||
{
|
||||
String line = lines[i];
|
||||
line.trim();
|
||||
if (line.new_toLower().startsWith("@include") && line.len() > 8)
|
||||
{
|
||||
line.substr(8).trim();
|
||||
if (!line.startsWith("<") || !line.endsWith(">"))
|
||||
return false;
|
||||
line.substr(1, line.len() - 1).trim();
|
||||
auto file_lines = __load_file(line);
|
||||
if (file_lines.size() == 0)
|
||||
return false;
|
||||
lines.erase(lines.begin() + i);
|
||||
if (__can_file_be_included(file_lines))
|
||||
{
|
||||
lines.insert(lines.begin() + i, file_lines.begin(), file_lines.end());
|
||||
included = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(included);
|
||||
m_lines = lines;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<String> IncludePreprocessor::__load_file(const String& filePath)
|
||||
{
|
||||
const auto& include_dirs = Assembler::Application::args.include_directories;
|
||||
|
||||
if (ostd::FileSystem::fileExists(m_directory + filePath))
|
||||
{
|
||||
ostd::TextFileBuffer file(m_directory + filePath);
|
||||
String source = file.rawContent();
|
||||
return String(source.replaceAll("\t", " ")).tokenize("\n", false).getRawData();
|
||||
}
|
||||
|
||||
for (const auto& dir : include_dirs)
|
||||
{
|
||||
if (ostd::FileSystem::fileExists(dir + filePath))
|
||||
{
|
||||
ostd::TextFileBuffer file(dir + filePath);
|
||||
String source = file.rawContent();
|
||||
return String(source.replaceAll("\t", " ")).tokenize("\n", false).getRawData();
|
||||
}
|
||||
}
|
||||
|
||||
return { }; //TODO: Error
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +1,20 @@
|
|||
#include <ostd/utils/Defines.hpp>
|
||||
#include "Assembler.hpp"
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <ostd/IOHandlers.hpp>
|
||||
|
||||
ostd::legacy::ConsoleOutputHandler out;
|
||||
|
||||
|
||||
struct tCommandLineArgs
|
||||
{
|
||||
ostd::String source_file_path = "";
|
||||
ostd::String dest_file_path = "";
|
||||
bool save_disassembly = false;
|
||||
bool verbose = false;
|
||||
ostd::String disassembly_file_path = "";
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
tCommandLineArgs args;
|
||||
if (argc < 4)
|
||||
{
|
||||
out.col("red").p("Error: too few arguments.").nl();
|
||||
out.col("red").p(" Usage: ./dasm <source> -o <destination> [...options...]").resetColors().nl();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.source_file_path = argv[1];
|
||||
for (int32_t i = 2; i < argc; i++)
|
||||
{
|
||||
ostd::StringEditor edit(argv[i]);
|
||||
if (edit.str() == "-o")
|
||||
{
|
||||
if (i == argc - 1)
|
||||
break; //TODO: Warning
|
||||
i++;
|
||||
args.dest_file_path = argv[i];
|
||||
}
|
||||
else if (edit.str() == "--save-disassembly")
|
||||
{
|
||||
if (i == argc - 1)
|
||||
break; //TODO: Warning
|
||||
i++;
|
||||
args.disassembly_file_path = argv[i];
|
||||
args.save_disassembly = true;
|
||||
}
|
||||
else if (edit.str() == "--verbose")
|
||||
args.verbose = true;
|
||||
}
|
||||
}
|
||||
|
||||
i32 rValue = dragon::code::Assembler::Application::loadArguments(argc, argv);
|
||||
if (rValue == dragon::code::Assembler::Application::RETURN_VAL_CLOSE_PROGRAM)
|
||||
return dragon::code::Assembler::Application::RETURN_VAL_EXIT_SUCCESS;
|
||||
if (rValue != dragon::code::Assembler::Application::RETURN_VAL_EXIT_SUCCESS)
|
||||
return rValue;
|
||||
auto& args = dragon::code::Assembler::Application::args;
|
||||
dragon::code::Assembler::saveExports = args.save_exports;
|
||||
dragon::code::Assembler::debugMode = args.debug_mode;
|
||||
dragon::code::Assembler::cpuExtensions = args.cpu_extensions;
|
||||
dragon::code::Assembler::assembleToFile(args.source_file_path, args.dest_file_path);
|
||||
if (args.verbose)
|
||||
dragon::code::Assembler::tempPrint();
|
||||
|
||||
dragon::code::Assembler::printProgramInfo(args.verbose_level);
|
||||
if (args.save_disassembly)
|
||||
dragon::code::Assembler::saveDisassemblyToFile(args.disassembly_file_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return dragon::code::Assembler::Application::RETURN_VAL_EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
32
src/debugger/Data.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "../tools/GlobalData.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace debugger
|
||||
{
|
||||
struct Run
|
||||
{
|
||||
AddressType offset;
|
||||
stdvec<i8> old_bytes;
|
||||
stdvec<i8> new_bytes;
|
||||
};
|
||||
struct Keyframe
|
||||
{
|
||||
u64 cycle;
|
||||
stdvec<i8> full_state; // entire memory image at this cycle
|
||||
};
|
||||
struct CycleDiff
|
||||
{
|
||||
u64 cycle;
|
||||
stdvec<Run> runs; // empty if nothing changed
|
||||
};
|
||||
struct History
|
||||
{
|
||||
u32 keyframe_interval { 1000 };
|
||||
stdvec<Keyframe> keyframes; // one every `interval` cycles
|
||||
stdvec<CycleDiff> diffs; // one per cycle (including keyframe cycles, optional)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,829 +0,0 @@
|
|||
#include "Debugger.hpp"
|
||||
#include "../runtime/DragonRuntime.hpp"
|
||||
#include "DisassemblyLoader.hpp"
|
||||
#include <ostd/Defines.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
//Debugger::Utils
|
||||
DisassemblyList Debugger::Utils::findCodeRegion(const DisassemblyList& code, uint16_t address, uint16_t codeRegionMargin)
|
||||
{
|
||||
if (code.size() <= (codeRegionMargin * 2) + 1) return code;
|
||||
std::vector<dragon::code::Assembler::tDisassemblyLine> codeRegion;
|
||||
uint16_t start = 0;
|
||||
uint16_t end = (codeRegionMargin * 2);
|
||||
for (int32_t i = 0; i < code.size(); i++)
|
||||
{
|
||||
if (code[i].addr != address) continue;
|
||||
if (i + 1 <= codeRegionMargin) break;
|
||||
if (code.size() - (i + 1) < codeRegionMargin)
|
||||
{
|
||||
end = code.size() - 1;
|
||||
start = end - ((codeRegionMargin * 2) + 1);
|
||||
break;
|
||||
}
|
||||
start = i - codeRegionMargin;
|
||||
end = i + codeRegionMargin;
|
||||
break;
|
||||
}
|
||||
for (int16_t i = start; i <= end; i++)
|
||||
codeRegion.push_back(code[i]);
|
||||
return codeRegion;
|
||||
}
|
||||
|
||||
ostd::String Debugger::Utils::findSymbol(const DisassemblyList& labels, uint16_t address)
|
||||
{
|
||||
for (auto& label : labels)
|
||||
{
|
||||
if (label.addr == address)
|
||||
return label.code;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
uint16_t Debugger::Utils::findSymbol(const DisassemblyList& labels, const ostd::StringEditor& symbol)
|
||||
{
|
||||
for (auto& label : labels)
|
||||
{
|
||||
if (label.code == symbol.str())
|
||||
return label.addr;
|
||||
}
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
bool Debugger::Utils::isValidLabelNameChar(char c)
|
||||
{
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_');
|
||||
}
|
||||
|
||||
ostd::StringEditor Debugger::Utils::fillString(const ostd::StringEditor& str, char fill, int32_t totalLength)
|
||||
{
|
||||
int32_t fillLen = totalLength - str.len();
|
||||
if (fillLen < 1) return str;
|
||||
ostd::StringEditor newStr = str;
|
||||
newStr.add(ostd::Utils::duplicateChar(fill, fillLen));
|
||||
return newStr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Debugger::Display
|
||||
void Debugger::Display::colorizeInstructionBody(const ostd::String& instBody, bool currentLine, const DisassemblyList& labelList)
|
||||
{
|
||||
ostd::RegexRichString rgxrstr(instBody);
|
||||
rgxrstr.fg("\\{|\\}|\\+|\\*|\\-|\\/|\\(|\\)|\\[|\\]", "Red"); //Operators
|
||||
rgxrstr.fg("0x[0-9A-Fa-f]+|0b[0-1]+|(?<!\\w)[0-9]+(?!\\w)", "BrightYellow"); //Number Constants
|
||||
rgxrstr.fg("(?<!\\w)(r[1-9]|r10|fl|pp|rv|fp|sp|ip|acc)(?!\\w)", "BrightGreen", true); //Registers
|
||||
rgxrstr.col("\\$\\w+", "Cyan", "Black"); //Labels
|
||||
ostd::StringEditor instEdit = rgxrstr.getRawString();
|
||||
for (auto& label : labelList)
|
||||
{
|
||||
int32_t index = -1;
|
||||
ostd::StringEditor labelEdit = label.code;
|
||||
labelEdit.trim();
|
||||
while ((index = instEdit.indexOf(labelEdit.str(), index + 1)) != -1)
|
||||
{
|
||||
if (index + labelEdit.str().length() < instEdit.len() && Utils::isValidLabelNameChar(instEdit.at(index + labelEdit.str().length())))
|
||||
continue;
|
||||
ostd::String instStr = instEdit.str();
|
||||
instStr.replace(index, labelEdit.str().length(), labelEdit.str() + "[@@ style foreground:brightgray](" + ostd::Utils::getHexStr(label.addr, true, 2) + ")[@@/]");
|
||||
instEdit = instStr;
|
||||
}
|
||||
}
|
||||
rgxrstr.setRawString(instEdit);
|
||||
out.p("\t").pStyled(rgxrstr);
|
||||
if (currentLine)
|
||||
out.p(" ").col(ostd::legacy::ConsoleCol::OnYellow).col(ostd::legacy::ConsoleCol::Black).p(" <-- ");
|
||||
out.nl();
|
||||
out.reset().resetColors();
|
||||
}
|
||||
|
||||
void Debugger::Display::colorCodeInstructions(const ostd::String& inst, bool currentLine, const DisassemblyList& labelList)
|
||||
{
|
||||
ostd::StringEditor instEditor = inst;
|
||||
ostd::StringEditor instBody = "";
|
||||
ostd::StringEditor instHead = inst;
|
||||
instEditor.trim();
|
||||
if (instEditor.contains(" "))
|
||||
{
|
||||
instHead = instEditor.substr(0, instEditor.indexOf(" "));
|
||||
instBody = instEditor.substr(instEditor.indexOf(" "));
|
||||
}
|
||||
if (currentLine)
|
||||
{
|
||||
out.col(ostd::legacy::ConsoleCol::OnYellow).col(ostd::legacy::ConsoleCol::Black);
|
||||
}
|
||||
else if (instHead.str() == "call" || instHead.str() == "ret" || instHead.str() == "int" || instHead.str() == "rti")
|
||||
out.col(ostd::legacy::ConsoleCol::OnBrightRed).col(ostd::legacy::ConsoleCol::White);
|
||||
else if (instHead.str() == "hlt" || instHead.str() == "debug_break")
|
||||
out.col(ostd::legacy::ConsoleCol::Red);
|
||||
else if (instHead.str() == "nop")
|
||||
out.col(ostd::legacy::ConsoleCol::Gray);
|
||||
else
|
||||
out.col(ostd::legacy::ConsoleCol::Blue);
|
||||
out.p(instHead);
|
||||
out.reset().resetColors();
|
||||
colorizeInstructionBody(instBody.str(), currentLine, labelList);
|
||||
}
|
||||
|
||||
void Debugger::Display::printPrompt(void)
|
||||
{
|
||||
out.col(ostd::legacy::ConsoleCol::Magenta).p(" #/> ").col(ostd::legacy::ConsoleCol::White);
|
||||
}
|
||||
|
||||
void Debugger::Display::printStep(void)
|
||||
{
|
||||
out.clear();
|
||||
int32_t codeRegionSpan = 15;
|
||||
auto codeRegion = Utils::findCodeRegion(debugger.code, debugger.currentAddress, codeRegionSpan);
|
||||
for (int32_t i = 0; i < codeRegion.size(); i++)
|
||||
{
|
||||
auto& _da = codeRegion[i];
|
||||
bool currentLine = _da.addr == debugger.currentAddress;
|
||||
ostd::String label = Utils::findSymbol(debugger.labels, _da.addr);
|
||||
bool specialSection = _da.code.starts_with("[") &&_da.code.ends_with("]");
|
||||
if (label.length() < debugger.labelLineLength)
|
||||
{
|
||||
label += ostd::Utils::duplicateChar(' ', debugger.labelLineLength - label.length());
|
||||
}
|
||||
else if (label.length() > debugger.labelLineLength)
|
||||
{
|
||||
ostd::StringEditor edit(label);
|
||||
edit = edit.substr(0, debugger.labelLineLength - 3);
|
||||
edit.add("...");
|
||||
label = edit.str();
|
||||
}
|
||||
out.col(ostd::legacy::ConsoleCol::Gray).p(label).p(" ");
|
||||
if (currentLine)
|
||||
{
|
||||
out.col(ostd::legacy::ConsoleCol::Black).col(ostd::legacy::ConsoleCol::OnYellow).p(ostd::Utils::getHexStr(_da.addr, true, 2)).p(" ").reset();;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (specialSection)
|
||||
out.col(ostd::legacy::ConsoleCol::Cyan);
|
||||
else
|
||||
out.col(ostd::legacy::ConsoleCol::BrightGray);
|
||||
out.p(ostd::Utils::getHexStr(_da.addr, true, 2)).p(" ");
|
||||
}
|
||||
if (specialSection)
|
||||
out.col(ostd::legacy::ConsoleCol::Cyan).p(_da.code).nl();
|
||||
else
|
||||
colorCodeInstructions(_da.code, currentLine, debugger.labels);
|
||||
out.reset();
|
||||
}
|
||||
int32_t cw = ostd::Utils::getConsoleWidth();
|
||||
ostd::String str = ostd::Utils::duplicateChar('#', cw);
|
||||
out.col(ostd::legacy::ConsoleCol::OnYellow).col(ostd::legacy::ConsoleCol::Black).p(str).reset().nl();
|
||||
}
|
||||
|
||||
void Debugger::Display::printDiff(void)
|
||||
{
|
||||
out.clear();
|
||||
|
||||
ostd::StringEditor str;
|
||||
str.add("|===============|================PREV================|================CURR================|=====|====REG====|====REG====|");
|
||||
str.add("\n");
|
||||
str.add("| InstAddr: |*%PREV_INST_ADDR%*******************|*%CURR_INST_ADDR%*******************| R1 |*%PREV_R1%*|*%CURR_R1%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| Code: | ---- |*%CURR_CODE%************************| R2 |*%PREV_R2%*|*%CURR_R2%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| StackFrame: |*%PREV_STACK_FRAME%*****************|*%CURR_STACK_FRAME%*****************| R3 |*%PREV_R3%*|*%CURR_R3%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| DBG BRK: |*%PREV_DBG_BRK%*********************|*%CURR_DBG_BRK%*********************| R4 |*%PREV_R4%*|*%CURR_R4%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| INT Handler: |*%PREV_INT_HANDLER%*****************|*%CURR_INT_HANDLER%*****************| R5 |*%PREV_R5%*|*%CURR_R5%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| BIOS Mode: |*%PREV_BIOS_MODE%*******************|**%CURR_BIOS_MODE%******************| R6 |*%PREV_R6%*|*%CURR_R6%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| IP: |*%PREV_IP%**************************|**%CURR_IP%*************************| R7 |*%PREV_R7%*|*%CURR_R7%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| SP: |*%PREV_SP%**************************|**%CURR_SP%*************************| R8 |*%PREV_R8%*|*%CURR_R8%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| FP: |*%PREV_FP%**************************|**%CURR_FP%*************************| R9 |*%PREV_R9%*|*%CURR_R9%*|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|");
|
||||
str.add("\n");
|
||||
str.add("| RV: |*%PREV_RV%**************************|**%CURR_RV%*************************| R10 |*%PREV_R10%|*%CURR_R10%|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|=====|===========|===========|");
|
||||
str.add("\n");
|
||||
str.add("| PP: |*%PREV_PP%**************************|**%CURR_PP%*************************|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|");
|
||||
str.add("\n");
|
||||
str.add("| FL: |*%PREV_FL%**************************|**%CURR_FL%*************************|");
|
||||
str.add("\n");
|
||||
str.add("|---------------|------------------------------------|------------------------------------|");
|
||||
str.add("\n");
|
||||
str.add("| ACC: |*%PREV_ACC%*************************|**%CURR_ACC%************************|");
|
||||
str.add("\n");
|
||||
str.add("|===============|====================================|====================================|");
|
||||
|
||||
|
||||
str.replaceAll("*", "");
|
||||
int32_t item_len = 36;
|
||||
const dragon::DragonRuntime::tMachineDebugInfo& minfo = dragon::DragonRuntime::getMachineInfoDiff();
|
||||
ostd::StringEditor tmp = " ", tmpStyle = "";
|
||||
|
||||
//Instruction Address
|
||||
{
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionAddress, true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_INST_ADDR%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionAddress, true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionAddress != minfo.previousInstructionAddress)
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_INST_ADDR%", tmpStyle.str());
|
||||
}
|
||||
|
||||
//Code
|
||||
{
|
||||
tmp = " ", tmpStyle = "";
|
||||
ostd::StringEditor prevCode = " (";
|
||||
prevCode.add(minfo.previousInstructionOpCode).add(") ");
|
||||
for (int32_t i = 0; i < minfo.previousInstructionFootprintSize; i++)
|
||||
prevCode.add(ostd::Utils::getHexStr(minfo.previousInstructionFootprint[i], false, 1)).add(" ");
|
||||
tmp.add(prevCode.str());
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightGray]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_CODE%", tmpStyle.str());
|
||||
|
||||
// tmp = " ";
|
||||
// ostd::StringEditor currCode = " (";
|
||||
// currCode.add(minfo.currentInstructionOpCode).add(") ");
|
||||
// for (int32_t i = 0; i < minfo.currentInstructionFootprintSize; i++)
|
||||
// currCode.add(ostd::Utils::getHexStr(minfo.currentInstructionFootprint[i], false, 1)).add(" ");
|
||||
// tmp.add(currCode.str());
|
||||
// tmp = fillString(tmp, ' ', item_len);
|
||||
// if (currCode.str() != prevCode.str())
|
||||
// tmpStyle = "[@@style foreground:Black,background:Yellow]";
|
||||
// else
|
||||
// tmpStyle = "[@@style foreground:Blue]";
|
||||
// tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
// str.replaceAll("%CURR_CODE%", tmpStyle.str());
|
||||
}
|
||||
|
||||
//Stack Frame
|
||||
{
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionStackFrameSize, true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_STACK_FRAME%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionStackFrameSize, true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionStackFrameSize != minfo.previousInstructionStackFrameSize)
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_STACK_FRAME%", tmpStyle.str());
|
||||
}
|
||||
|
||||
//Debug Break
|
||||
{
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(STR_BOOL(minfo.previousInstructionDebugBreak));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_DBG_BRK%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(STR_BOOL(minfo.currentInstructionDebugBreak));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionDebugBreak != minfo.previousInstructionDebugBreak)
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_DBG_BRK%", tmpStyle.str());
|
||||
}
|
||||
|
||||
//INT Handler
|
||||
{
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(STR_BOOL(minfo.previousInstructionInterruptHandler));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_INT_HANDLER%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(STR_BOOL(minfo.currentInstructionInterruptHandler));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionInterruptHandler != minfo.previousInstructionInterruptHandler)
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_INT_HANDLER%", tmpStyle.str());
|
||||
}
|
||||
|
||||
//Bios Mode
|
||||
{
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(STR_BOOL(minfo.previousInstructionBiosMode));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_BIOS_MODE%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(STR_BOOL(minfo.currentInstructionBiosMode));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionBiosMode != minfo.previousInstructionBiosMode)
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_BIOS_MODE%", tmpStyle.str());
|
||||
}
|
||||
|
||||
//System Registers
|
||||
{
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::IP], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_IP%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::IP], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::IP] != minfo.previousInstructionRegisters[dragon::data::Registers::IP])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_IP%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::SP], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_SP%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::SP], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::SP] != minfo.previousInstructionRegisters[dragon::data::Registers::SP])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_SP%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::FP], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_FP%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::FP], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::FP] != minfo.previousInstructionRegisters[dragon::data::Registers::FP])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_FP%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::RV], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_RV%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::RV], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::RV] != minfo.previousInstructionRegisters[dragon::data::Registers::RV])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_RV%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::PP], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_PP%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::PP], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::PP] != minfo.previousInstructionRegisters[dragon::data::Registers::PP])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_PP%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::FL], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_FL%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::FL], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::FL] != minfo.previousInstructionRegisters[dragon::data::Registers::FL])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_FL%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::ACC], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_ACC%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::ACC], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::ACC] != minfo.previousInstructionRegisters[dragon::data::Registers::ACC])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_ACC%", tmpStyle.str());
|
||||
}
|
||||
|
||||
item_len = 11;
|
||||
//General Registers
|
||||
{
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R1], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R1%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R1], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R1] != minfo.previousInstructionRegisters[dragon::data::Registers::R1])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R1%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R2], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R2%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R2], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R2] != minfo.previousInstructionRegisters[dragon::data::Registers::R2])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R2%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R3], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R3%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R3], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R3] != minfo.previousInstructionRegisters[dragon::data::Registers::R3])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R3%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R4], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R4%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R4], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R4] != minfo.previousInstructionRegisters[dragon::data::Registers::R4])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R4%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R5], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R5%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R5], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R5] != minfo.previousInstructionRegisters[dragon::data::Registers::R5])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R5%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R6], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R6%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R6], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R6] != minfo.previousInstructionRegisters[dragon::data::Registers::R6])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R6%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R7], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R7%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R7], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R7] != minfo.previousInstructionRegisters[dragon::data::Registers::R7])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R7%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R8], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R8%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R8], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R8] != minfo.previousInstructionRegisters[dragon::data::Registers::R8])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R8%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R9], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R9%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R9], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R9] != minfo.previousInstructionRegisters[dragon::data::Registers::R9])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R9%", tmpStyle.str());
|
||||
|
||||
|
||||
|
||||
|
||||
tmp = " ", tmpStyle = "";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R10], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%PREV_R10%", tmpStyle.str());
|
||||
|
||||
tmp = " ";
|
||||
tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R10], true, 2));
|
||||
tmp = Utils::fillString(tmp, ' ', item_len);
|
||||
if (minfo.currentInstructionRegisters[dragon::data::Registers::R10] != minfo.previousInstructionRegisters[dragon::data::Registers::R10])
|
||||
tmpStyle = "[@@style foreground:Black,background:BrightRed]";
|
||||
else
|
||||
tmpStyle = "[@@style foreground:Blue]";
|
||||
tmpStyle.add(tmp.str()).add("[@@/]");
|
||||
str.replaceAll("%CURR_R10%", tmpStyle.str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostd::RegexRichString rgxstr(str);
|
||||
rgxstr.fg("InstAddr|Code|StackFrame|DBG BRK|INT Handler|BIOS Mode", "Magenta");
|
||||
rgxstr.fg("IP|SP|FP|RV|PP|FL|ACC", "Cyan");
|
||||
rgxstr.fg("R10|R2|R3|R4|R5|R6|R7|R8|R9|R1", "BrightGreen");
|
||||
rgxstr.fg("PREV", "Red");
|
||||
rgxstr.fg("CURR", "Green");
|
||||
out.pStyled(rgxstr);
|
||||
|
||||
out.nl().nl().col(ostd::legacy::ConsoleCol::Yellow).p("Pres <Enter> to continue execution...").nl().reset();
|
||||
std::cin.get();
|
||||
}
|
||||
|
||||
void Debugger::Display::printTrackedAddresses(const std::vector<uint16_t>& trackedAddresses)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ostd::StringEditor Debugger::Display::changeScreen(void)
|
||||
{
|
||||
if (debugger.command.str() == "diff")
|
||||
{
|
||||
printDiff();
|
||||
printStep();
|
||||
return getCommandInput();
|
||||
}
|
||||
else if (debugger.command.str() == "tracker")
|
||||
{
|
||||
printTrackedAddresses(debugger.trackedAddresses);
|
||||
printStep();
|
||||
return getCommandInput();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Debugger
|
||||
void Debugger::processErrors(void)
|
||||
{
|
||||
if (!dragon::DragonRuntime::hasError()) return;
|
||||
while (dragon::data::ErrorHandler::hasError())
|
||||
{
|
||||
auto err = dragon::data::ErrorHandler::popError();
|
||||
out.nl().col(ostd::legacy::ConsoleCol::Red).p("Error ").p(ostd::Utils::getHexStr(err.code, true, 8)).p(": ").p(err.text).nl();
|
||||
}
|
||||
debugger.args.step_exec = true;
|
||||
}
|
||||
|
||||
int32_t Debugger::loadArguments(int argc, char** argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
out.col("red").p("Error, too few arguments.").resetColors().nl();
|
||||
return 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
debugger.args.machine_config_path = argv[1];
|
||||
for (int32_t i = 2; i < argc; i++)
|
||||
{
|
||||
ostd::StringEditor edit(argv[i]);
|
||||
if (edit.str() == "--verbose-load")
|
||||
debugger.args.verbose_load = true;
|
||||
else if (edit.str() == "--step-exec")
|
||||
debugger.args.step_exec = true;
|
||||
else if (edit.str() == "--track-step-diff")
|
||||
debugger.args.track_step_diff = true;
|
||||
else if (edit.str() == "--hide-vdisplay")
|
||||
debugger.args.hide_virtual_display = true;
|
||||
else if (edit.str() == "--auto-start")
|
||||
debugger.args.auto_start_debug = true;
|
||||
else if (edit.str() == "--force-load")
|
||||
{
|
||||
if ((argc - 1) - i < 2)
|
||||
break; //TODO: Warning
|
||||
i++;
|
||||
debugger.args.force_load_file = argv[i];
|
||||
i++;
|
||||
edit = argv[i];
|
||||
if (!edit.isNumeric())
|
||||
continue; //TODO: Error
|
||||
debugger.args.force_load_mem_offset = (uint16_t)edit.toInt();
|
||||
debugger.args.force_load = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Debugger::initRuntime(void)
|
||||
{
|
||||
int32_t init_state = dragon::DragonRuntime::initMachine(debugger.args.machine_config_path, debugger.args.verbose_load, debugger.args.track_step_diff, debugger.args.hide_virtual_display);
|
||||
if (init_state != 0) return init_state; //TODO: Error
|
||||
|
||||
if (debugger.args.force_load)
|
||||
dragon::DragonRuntime::forceLoad(debugger.args.force_load_file, debugger.args.force_load_mem_offset);
|
||||
|
||||
dragon::DisassemblyLoader::loadDirectory(debugger.disassemblyDirectory.str());
|
||||
debugger.code = dragon::DisassemblyLoader::getCodeTable();
|
||||
debugger.labels = dragon::DisassemblyLoader::getLabelTable();
|
||||
debugger.data = dragon::DisassemblyLoader::getDataTable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ostd::StringEditor Debugger::getCommandInput(void)
|
||||
{
|
||||
ostd::String cmd;
|
||||
std::getline(std::cin, cmd);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <ostd/IOHandlers.hpp>
|
||||
#include "../assembler/Assembler.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
typedef std::vector<dragon::code::Assembler::tDisassemblyLine> DisassemblyList;
|
||||
|
||||
class Debugger
|
||||
{
|
||||
public: struct tCommandLineArgs
|
||||
{
|
||||
inline tCommandLineArgs(void) { }
|
||||
ostd::String machine_config_path = "";
|
||||
bool verbose_load = false;
|
||||
bool force_load = false;
|
||||
bool step_exec = false;
|
||||
bool track_step_diff = false;
|
||||
bool auto_start_debug = false;
|
||||
bool hide_virtual_display = false;
|
||||
ostd::String force_load_file = "";
|
||||
uint16_t force_load_mem_offset = 0x00;
|
||||
};
|
||||
public: struct tDebuggerData
|
||||
{
|
||||
inline tDebuggerData(void) { }
|
||||
tCommandLineArgs args;
|
||||
DisassemblyList code;
|
||||
DisassemblyList labels;
|
||||
DisassemblyList data;
|
||||
std::vector<uint16_t> trackedAddresses;
|
||||
ostd::StringEditor command;
|
||||
int32_t labelLineLength { 20 };
|
||||
uint16_t currentAddress { 0 };
|
||||
bool userQuit { false };
|
||||
ostd::StringEditor disassemblyDirectory { "disassembly" };
|
||||
};
|
||||
public: class Utils
|
||||
{
|
||||
public:
|
||||
static DisassemblyList findCodeRegion(const DisassemblyList& code, uint16_t address, uint16_t codeRegionMargin);
|
||||
static ostd::String findSymbol(const DisassemblyList& labels, uint16_t address);
|
||||
static uint16_t findSymbol(const DisassemblyList& labels, const ostd::StringEditor& symbol);
|
||||
static bool isValidLabelNameChar(char c);
|
||||
static ostd::StringEditor fillString(const ostd::StringEditor& str, char fill, int32_t totalLength); //TODO: Implement in omnia-framework
|
||||
};
|
||||
public: class Display
|
||||
{
|
||||
public:
|
||||
static void colorizeInstructionBody(const ostd::String& instBody, bool currentLine, const DisassemblyList& labelList);
|
||||
static void colorCodeInstructions(const ostd::String& inst, bool currentLine, const DisassemblyList& labelList);
|
||||
static void printPrompt(void);
|
||||
static void printStep(void);
|
||||
static void printDiff(void);
|
||||
static void printTrackedAddresses(const std::vector<uint16_t>& trackedAddresses);
|
||||
static ostd::StringEditor changeScreen(void);
|
||||
};
|
||||
public:
|
||||
static void processErrors(void);
|
||||
static int32_t loadArguments(int argc, char** argv);
|
||||
static int32_t initRuntime(void);
|
||||
static ostd::StringEditor getCommandInput(void);
|
||||
static inline tDebuggerData& data(void) { return debugger; }
|
||||
static inline ostd::legacy::ConsoleOutputHandler& output(void) { return out; }
|
||||
|
||||
private:
|
||||
inline static tDebuggerData debugger;
|
||||
inline static ostd::legacy::ConsoleOutputHandler out;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,18 +1,21 @@
|
|||
#include "DisassemblyLoader.hpp"
|
||||
|
||||
#include <ostd/File.hpp>
|
||||
#include <ostd/Serial.hpp>
|
||||
#include <ostd/io/File.hpp>
|
||||
#include <ostd/io/FileSystem.hpp>
|
||||
#include <ostd/io/Memory.hpp>
|
||||
#include "../tools/LegacyOstdSerial.hpp"
|
||||
|
||||
#include "../tools/Utils.hpp"
|
||||
#include <algorithm>
|
||||
#include <ostd/string/String.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
const DisassemblyTable DisassemblyTable::DefaultObject;
|
||||
|
||||
void DisassemblyTable::init(const ostd::String& filePath)
|
||||
void DisassemblyTable::init(const String& filePath)
|
||||
{
|
||||
ostd::ByteStream stream;
|
||||
if (!ostd::Utils::loadByteStreamFromFile(filePath, stream))
|
||||
if (!ostd::Memory::loadByteStreamFromFile(filePath, stream))
|
||||
{
|
||||
m_initialized = false;
|
||||
return;
|
||||
|
|
@ -22,33 +25,26 @@ namespace dragon
|
|||
|
||||
void DisassemblyTable::load_data(ostd::ByteStream& stream)
|
||||
{
|
||||
constexpr int32_t MODE_CODE = 0, MODE_DATA = 1, MODE_LABELS = 2;
|
||||
int32_t mode = MODE_CODE;
|
||||
constexpr i32 MODE_CODE = 0, MODE_DATA = 1, MODE_LABELS = 2;
|
||||
i32 mode = MODE_CODE;
|
||||
ostd::serial::SerialIO serializer(stream, ostd::serial::SerialIO::tEndianness::BigEndian);
|
||||
ostd::StreamIndex addr = 0;
|
||||
int32_t line_addr = 0;
|
||||
int8_t line_code_char = 0;
|
||||
ostd::String header_string = "";
|
||||
i32 line_addr = 0;
|
||||
i16 data_size = 1;
|
||||
i8 line_code_char = 0;
|
||||
String header_string = "";
|
||||
serializer.r_NullTerminatedString(0, header_string);
|
||||
if (header_string != "{ DRAGON_DEBUG_DISASSEMBLY }") return;
|
||||
addr += (header_string.length() + 1) * ostd::tTypeSize::BYTE;
|
||||
addr += (header_string.len() + 1) * ostd::tTypeSize::BYTE;
|
||||
while (addr < serializer.size())
|
||||
{
|
||||
serializer.r_DWord(addr, line_addr);
|
||||
addr += ostd::tTypeSize::DWORD;
|
||||
// ostd::ByteStream str_stream;
|
||||
// serializer.r_Byte(addr, line_code_char);
|
||||
// addr += ostd::tTypeSize::BYTE;
|
||||
// do
|
||||
// {
|
||||
// str_stream.push_back(line_code_char);
|
||||
// serializer.r_Byte(addr, line_code_char);
|
||||
// addr += ostd::tTypeSize::BYTE;
|
||||
// } while(line_code_char != 0);
|
||||
// ostd::String code_line = ostd::Utils::byteStreamToString(str_stream);
|
||||
ostd::String code_line = "";
|
||||
serializer.r_Word(addr, data_size);
|
||||
addr += ostd::tTypeSize::WORD;
|
||||
String code_line = "";
|
||||
serializer.r_NullTerminatedString(addr, code_line);
|
||||
addr += (code_line.length() + 1) * ostd::tTypeSize::BYTE;
|
||||
addr += (code_line.len() + 1) * ostd::tTypeSize::BYTE;
|
||||
if (code_line == "{ DATA }")
|
||||
{
|
||||
mode = MODE_DATA;
|
||||
|
|
@ -67,21 +63,22 @@ namespace dragon
|
|||
code::Assembler::tDisassemblyLine line;
|
||||
line.addr = line_addr;
|
||||
line.code = code_line;
|
||||
line.size = data_size;
|
||||
if (mode == MODE_CODE)
|
||||
{
|
||||
ostd::StringEditor codeEdit(line.code);
|
||||
String codeEdit(line.code);
|
||||
codeEdit.trim();
|
||||
if (codeEdit.contains(" "))
|
||||
{
|
||||
ostd::StringEditor part1 = codeEdit.substr(0, codeEdit.indexOf(" "));
|
||||
ostd::StringEditor part2 = codeEdit.substr(codeEdit.indexOf(" ") + 1);
|
||||
String part1 = codeEdit.new_substr(0, codeEdit.indexOf(" "));
|
||||
String part2 = codeEdit.new_substr(codeEdit.indexOf(" ") + 1);
|
||||
part1.trim();
|
||||
part2.trim();
|
||||
int32_t opCodeLen = 10;
|
||||
i32 opCodeLen = 10;
|
||||
if (part1.len() < opCodeLen)
|
||||
{
|
||||
codeEdit = part1.str() + ostd::Utils::duplicateChar(' ', opCodeLen - part1.len()) + part2.str();
|
||||
line.code = codeEdit.str();
|
||||
codeEdit = part1 + String::duplicateChar(' ', opCodeLen - part1.len()) + part2;
|
||||
line.code = codeEdit;
|
||||
}
|
||||
}
|
||||
m_code.push_back(line);
|
||||
|
|
@ -96,14 +93,14 @@ namespace dragon
|
|||
|
||||
|
||||
|
||||
void DisassemblyLoader::loadDirectory(const ostd::String& directoryPath)
|
||||
void DisassemblyLoader::loadDirectory(const String& directoryPath)
|
||||
{
|
||||
auto list = ostd::Utils::listFilesInDirectory(directoryPath);
|
||||
auto list = ostd::FileSystem::listFilesInDirectory(directoryPath);
|
||||
for (auto& path : list)
|
||||
loadFile(path.string());
|
||||
}
|
||||
|
||||
const DisassemblyTable& DisassemblyLoader::loadFile(const ostd::String& filePath)
|
||||
const DisassemblyTable& DisassemblyLoader::loadFile(const String& filePath)
|
||||
{
|
||||
DisassemblyTable table(filePath);
|
||||
if (!table.isInitialized()) return DisassemblyTable::DefaultObject; //TODO: Error
|
||||
|
|
@ -116,6 +113,7 @@ namespace dragon
|
|||
std::vector<code::Assembler::tDisassemblyLine> fullTable;
|
||||
for (auto& table : m_tables)
|
||||
fullTable.insert(fullTable.end(), table.getCodeTable().begin(), table.getCodeTable().end());
|
||||
std::sort(fullTable.begin(), fullTable.end());
|
||||
return fullTable;
|
||||
}
|
||||
|
||||
|
|
@ -124,6 +122,7 @@ namespace dragon
|
|||
std::vector<code::Assembler::tDisassemblyLine> fullTable;
|
||||
for (auto& table : m_tables)
|
||||
fullTable.insert(fullTable.end(), table.getDataTable().begin(), table.getDataTable().end());
|
||||
std::sort(fullTable.begin(), fullTable.end());
|
||||
return fullTable;
|
||||
}
|
||||
|
||||
|
|
@ -132,6 +131,7 @@ namespace dragon
|
|||
std::vector<code::Assembler::tDisassemblyLine> fullTable;
|
||||
for (auto& table : m_tables)
|
||||
fullTable.insert(fullTable.end(), table.getLabelTable().begin(), table.getLabelTable().end());
|
||||
std::sort(fullTable.begin(), fullTable.end());
|
||||
return fullTable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "../assembler/Assembler.hpp"
|
||||
|
||||
#include <ostd/Types.hpp>
|
||||
#include <ostd/data/Types.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
|
|
@ -10,8 +10,8 @@ namespace dragon
|
|||
{
|
||||
public:
|
||||
inline DisassemblyTable(void) { m_initialized = false; }
|
||||
inline DisassemblyTable(const ostd::String& filePath) { init(filePath); }
|
||||
void init(const ostd::String& filePath);
|
||||
inline DisassemblyTable(const String& filePath) { init(filePath); }
|
||||
void init(const String& filePath);
|
||||
|
||||
inline const std::vector<code::Assembler::tDisassemblyLine>& getCodeTable(void) const { return m_code; }
|
||||
inline const std::vector<code::Assembler::tDisassemblyLine>& getDataTable(void) const { return m_data; }
|
||||
|
|
@ -27,7 +27,7 @@ namespace dragon
|
|||
std::vector<code::Assembler::tDisassemblyLine> m_labels;
|
||||
std::vector<code::Assembler::tDisassemblyLine> m_data;
|
||||
bool m_initialized { false };
|
||||
ostd::String m_filePath { "" };
|
||||
String m_filePath { "" };
|
||||
|
||||
public:
|
||||
static const DisassemblyTable DefaultObject;
|
||||
|
|
@ -36,8 +36,8 @@ namespace dragon
|
|||
class DisassemblyLoader
|
||||
{
|
||||
public:
|
||||
static void loadDirectory(const ostd::String& directoryPath);
|
||||
static const DisassemblyTable& loadFile(const ostd::String& filePath);
|
||||
static void loadDirectory(const String& directoryPath);
|
||||
static const DisassemblyTable& loadFile(const String& filePath);
|
||||
|
||||
static std::vector<code::Assembler::tDisassemblyLine> getCodeTable(void);
|
||||
static std::vector<code::Assembler::tDisassemblyLine> getDataTable(void);
|
||||
|
|
@ -46,4 +46,4 @@ namespace dragon
|
|||
private:
|
||||
inline static std::vector<DisassemblyTable> m_tables;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,100 +1,29 @@
|
|||
#include "Debugger.hpp"
|
||||
#include "../runtime/DragonRuntime.hpp"
|
||||
|
||||
#include <ostd/utils/Defines.hpp>
|
||||
// #include "../runtime/DragonRuntime.hpp"
|
||||
#include <ostd/utils/Signals.hpp>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
using namespace dragon;
|
||||
int32_t rValue = Debugger::loadArguments(argc, argv);
|
||||
if (rValue != 0) return rValue;
|
||||
rValue = Debugger::initRuntime();
|
||||
if (rValue != 0) return rValue;
|
||||
//Loading commandline arguments
|
||||
// i32 rValue = dragon::Debugger::loadArguments(argc, argv);
|
||||
// if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
// return 0;
|
||||
// if (rValue != 0) return rValue;
|
||||
|
||||
if (!Debugger::data().args.auto_start_debug)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Debugger::Display::printPrompt();
|
||||
Debugger::data().command = Debugger::getCommandInput();
|
||||
Debugger::data().command.trim().toLower();
|
||||
if (Debugger::data().command.str() == "r" || Debugger::data().command.str() == "run")
|
||||
break;
|
||||
else if (Debugger::data().command.str() == "q" || Debugger::data().command.str() == "quit")
|
||||
return rValue;
|
||||
else if (Debugger::data().command.startsWith("watch "))
|
||||
{
|
||||
Debugger::data().command = Debugger::data().command.substr(6);
|
||||
Debugger::data().command.trim();
|
||||
auto tokens = Debugger::data().command.tokenize();
|
||||
for (auto& addr : tokens)
|
||||
{
|
||||
Debugger::data().command = addr;
|
||||
if (Debugger::data().command.isNumeric())
|
||||
Debugger::data().trackedAddresses.push_back((uint16_t)Debugger::data().command.toInt());
|
||||
else if (Debugger::data().command.startsWith("$"))
|
||||
{
|
||||
uint16_t addr = Debugger::Utils::findSymbol(Debugger::data().data, Debugger::data().command);
|
||||
if (addr > 0)
|
||||
Debugger::data().trackedAddresses.push_back(addr);
|
||||
else
|
||||
{
|
||||
addr = Debugger::Utils::findSymbol(Debugger::data().labels, Debugger::data().command);
|
||||
if (addr > 0)
|
||||
Debugger::data().trackedAddresses.push_back(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// //Initializing the runtime
|
||||
// rValue = dragon::Debugger::initRuntime();
|
||||
// if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
// return 0;
|
||||
// if (rValue != 0) return rValue;
|
||||
|
||||
constexpr int32_t labelLineLen = 20;
|
||||
Debugger::data().currentAddress = dragon::DragonRuntime::cpu.readRegister(dragon::data::Registers::IP);
|
||||
// //Running top-level prompt
|
||||
// rValue = dragon::Debugger::topLevelPrompt();
|
||||
// if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
// return 0;
|
||||
// if (rValue != 0) return rValue;
|
||||
|
||||
bool userQuit = false;
|
||||
while (true)
|
||||
{
|
||||
Debugger::data().command.clr();
|
||||
bool result = false;
|
||||
bool hasError = false;
|
||||
if (!userQuit)
|
||||
{
|
||||
result = dragon::DragonRuntime::runStep(Debugger::data().trackedAddresses);
|
||||
hasError = dragon::DragonRuntime::hasError();
|
||||
Debugger::Display::printStep();
|
||||
Debugger::processErrors();
|
||||
}
|
||||
if (!result || userQuit)
|
||||
{
|
||||
Debugger::output().nl().col(ostd::legacy::ConsoleCol::Yellow).p("Execution Finished. Pres <Enter> to exit...").nl().reset();
|
||||
std::cin.get();
|
||||
break;
|
||||
}
|
||||
Debugger::Display::printPrompt();
|
||||
if (Debugger::data().args.step_exec || dragon::DragonRuntime::cpu.isInDebugBreakPoint())
|
||||
{
|
||||
Debugger::data().command = Debugger::getCommandInput();
|
||||
if (dragon::DragonRuntime::cpu.isInDebugBreakPoint())
|
||||
Debugger::data().args.step_exec = true;
|
||||
}
|
||||
Debugger::data().command.trim().toLower();
|
||||
while (Debugger::data().command.str() != "")
|
||||
{
|
||||
if (Debugger::data().command.str() == "q" || Debugger::data().command.str() == "quit")
|
||||
{
|
||||
userQuit = true;
|
||||
Debugger::data().command = "";
|
||||
}
|
||||
else if (Debugger::data().command.str() == "c" || Debugger::data().command.str() == "continue")
|
||||
{
|
||||
Debugger::data().args.step_exec = false;
|
||||
Debugger::data().command = "";
|
||||
}
|
||||
else
|
||||
Debugger::data().command = Debugger::Display::changeScreen();
|
||||
}
|
||||
Debugger::data().currentAddress = dragon::DragonRuntime::cpu.readRegister(dragon::data::Registers::IP);
|
||||
}
|
||||
// //Executing the runtime
|
||||
// return dragon::Debugger::executeRuntime();
|
||||
|
||||
return rValue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
#include "DebuggerWindow.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
class DebuggerWindow
|
||||
{
|
||||
|
||||
};
|
||||
} // namespace dragon
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
#include "RawTextRenderer.hpp"
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <ostd/Geometry.hpp>
|
||||
#include <ostd/Defines.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
void RawTextRenderer::initialize(void)
|
||||
{
|
||||
for (char c = ' '; c <= '~'; c++)
|
||||
characterMap[c] = getCharacterIndex(c);
|
||||
}
|
||||
|
||||
bool RawTextRenderer::drawString(ostd::String str, uint32_t column, uint32_t row, uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels, ostd::Color color, ostd::Color background)
|
||||
{
|
||||
ostd::StringEditor se(str);
|
||||
if (se.str() == "") return false;
|
||||
if (row >= CONSOLE_CHARS_V) return false;
|
||||
if (column >= CONSOLE_CHARS_H) return false;
|
||||
if (column + str.length() > CONSOLE_CHARS_H) return false;
|
||||
int32_t x = column * FONT_CHAR_W;
|
||||
int32_t y = row * FONT_CHAR_H;
|
||||
for (auto& c : str)
|
||||
{
|
||||
drawCharacter((uint8_t*)screenPixels, screenWidth, screenHeight, (uint8_t*)fontPixels, x, y, c, color, background);
|
||||
x += FONT_CHAR_W;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t RawTextRenderer::getCharacterIndex(char c)
|
||||
{
|
||||
using namespace ostd;
|
||||
|
||||
int32_t charIndex = (int)c - 32;
|
||||
IPoint charCoords = CONVERT_1D_2D(charIndex, FONT_H_CHARS);
|
||||
charCoords.x *= FONT_CHAR_W * 4;
|
||||
charCoords.y *= FONT_CHAR_H;
|
||||
charIndex = CONVERT_2D_1D(charCoords.x, charCoords.y, (FONT_H_CHARS * FONT_CHAR_W * 4));
|
||||
|
||||
return charIndex;
|
||||
}
|
||||
|
||||
ostd::Color RawTextRenderer::applyTint(ostd::Color baseColor, ostd::Color tintColor)
|
||||
{
|
||||
auto nBase = baseColor.getNormalizedColor();
|
||||
auto nTint = tintColor.getNormalizedColor();
|
||||
|
||||
float r = nBase.r * nTint.r;
|
||||
float g = nBase.r * nTint.g;
|
||||
float b = nBase.r * nTint.b;
|
||||
|
||||
ostd::Color::FloatCol nTinted(r, g, b, 1.0f);
|
||||
|
||||
return ostd::Color(nTinted);
|
||||
}
|
||||
|
||||
void RawTextRenderer::drawCharacter(uint8_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint8_t* fontPixels, int32_t x, int32_t y, char c, ostd::Color color, ostd::Color background)
|
||||
{
|
||||
using namespace ostd;
|
||||
int32_t charIndex = characterMap[c];
|
||||
IPoint charCoords = CONVERT_1D_2D(charIndex, (FONT_CHAR_W * FONT_H_CHARS * 4));
|
||||
|
||||
int32_t screenx = x * 4, screeny = y;
|
||||
|
||||
ostd::Color tintedColor;
|
||||
|
||||
bool applyBackground = false;
|
||||
for (int32_t y = charCoords.y; y < charCoords.y + (FONT_CHAR_H); y += 1)
|
||||
{
|
||||
for (int32_t x = charCoords.x; x < charCoords.x + (FONT_CHAR_W * 4); x += 4)
|
||||
{
|
||||
int32_t index = CONVERT_2D_1D(x, y, (FONT_CHAR_W * FONT_H_CHARS * 4));
|
||||
int32_t screenIndex = CONVERT_2D_1D(screenx, screeny, (screenWidth * 4));
|
||||
screenx += 4;
|
||||
if (fontPixels[index] == 0x00 && fontPixels[index + 1] == 0x00 && fontPixels[index + 2] == 0x00)
|
||||
{
|
||||
if (background.a == 0)
|
||||
continue;
|
||||
applyBackground = true;
|
||||
}
|
||||
if (applyBackground)
|
||||
{
|
||||
screenPixels[screenIndex] = 255;
|
||||
screenPixels[screenIndex + 1] = background.b;
|
||||
screenPixels[screenIndex + 2] = background.g;
|
||||
screenPixels[screenIndex + 3] = background.r;
|
||||
applyBackground = false;
|
||||
continue;
|
||||
}
|
||||
tintedColor = applyTint({ fontPixels[index], fontPixels[index + 1], fontPixels[index + 2], 255 }, color);
|
||||
screenPixels[screenIndex] = fontPixels[index + 3];
|
||||
screenPixels[screenIndex + 1] = tintedColor.b;
|
||||
screenPixels[screenIndex + 2] = tintedColor.g;
|
||||
screenPixels[screenIndex + 3] = tintedColor.r;
|
||||
}
|
||||
screeny += 1;
|
||||
screenx = x * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <ostd/Color.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
class RawTextRenderer
|
||||
{
|
||||
private:
|
||||
inline static std::unordered_map<char, int32_t> characterMap;
|
||||
|
||||
public:
|
||||
static void initialize(void);
|
||||
static bool drawString(ostd::String str, uint32_t column, uint32_t row, uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels, ostd::Color color = { 255, 255, 255, 255 }, ostd::Color background = { 255, 255, 255, 0 });
|
||||
|
||||
private:
|
||||
static int32_t getCharacterIndex(char c);
|
||||
static ostd::Color applyTint(ostd::Color baseColor, ostd::Color tintColor);
|
||||
static void drawCharacter(uint8_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint8_t* fontPixels, int32_t x, int32_t y, char c, ostd::Color color = { 255, 255, 255, 255 }, ostd::Color background = { 255, 255, 255, 0 });
|
||||
|
||||
public:
|
||||
inline static constexpr int32_t FONT_CHAR_W = 11;
|
||||
inline static constexpr int32_t FONT_CHAR_H = 26;
|
||||
inline static constexpr int32_t FONT_V_CHARS = 6;
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
#include "VirtualConsole.hpp"
|
||||
#include "RawTextRenderer.hpp"
|
||||
#include <ostd/Defines.hpp>
|
||||
|
||||
#include "../hardware/VirtualIODevices.hpp"
|
||||
#include "../hardware/VirtualCPU.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
void VirtualConsole::initialize(void)
|
||||
{
|
||||
m_windowWidth = RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::FONT_CHAR_W; //60 * 16;
|
||||
m_windowHeight = RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::FONT_CHAR_H; //60 * 9;
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
m_window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_windowWidth, m_windowHeight, SDL_WINDOW_RESIZABLE);
|
||||
SDL_SetWindowResizable(m_window, SDL_FALSE);
|
||||
m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight);
|
||||
m_screenTexture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, m_windowWidth, m_windowHeight);
|
||||
m_fontSurface = SDL_LoadBMP("font.bmp");
|
||||
if (m_fontSurface == NULL)
|
||||
out.bg(ostd::ConsoleColors::Red).p("Error loading font.").nl();
|
||||
m_fontPixels = (uint32_t*)m_fontSurface->pixels;
|
||||
m_screenPixels = (uint32_t*)malloc(m_windowWidth * m_windowHeight * 4);
|
||||
|
||||
dragon::RawTextRenderer::initialize();
|
||||
|
||||
vout.init(m_screenPixels, m_windowWidth, m_windowHeight, m_fontPixels);
|
||||
vout.enableFixedScreen();
|
||||
|
||||
m_palettes.push_back(new data::BiosVideoDefaultPalette); //TODO: Possible Memory Leak, palettes are never destroyed
|
||||
|
||||
m_initialized = true;
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
void VirtualConsole::update(void)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
Uint64 start = SDL_GetPerformanceCounter();
|
||||
handleEvents();
|
||||
if (m_redrawConsole)
|
||||
{
|
||||
uint8_t signal = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::Signal);
|
||||
switch (signal)
|
||||
{
|
||||
case tSignals::ClearScreen:
|
||||
m_clearMemory = true;
|
||||
break;
|
||||
case tSignals::Continue: break;
|
||||
default: break;
|
||||
}
|
||||
m_biosVideo.write8(hw::VirtualBIOSVideo::tRegisters::Signal, tSignals::Continue);
|
||||
drawConsole();
|
||||
m_redrawConsole = false;
|
||||
}
|
||||
finalizeRender();
|
||||
Uint64 end = SDL_GetPerformanceCounter();
|
||||
float elapsed = (end - start) / (float)SDL_GetPerformanceFrequency();
|
||||
m_redrawAccumulator += elapsed;
|
||||
if (m_redrawAccumulator >= 0.2f)
|
||||
{
|
||||
m_redrawConsole = true;
|
||||
m_redrawAccumulator = 0.0f;
|
||||
}
|
||||
end = SDL_GetPerformanceCounter();
|
||||
elapsed = (end - start) / (float)SDL_GetPerformanceFrequency();
|
||||
m_timeAccumulator += elapsed;
|
||||
if (m_timeAccumulator >= 0.5f)
|
||||
{
|
||||
m_title.clr().add("FPS: ").addi((int)(1.0f / elapsed));
|
||||
SDL_SetWindowTitle(m_window, m_title.c_str());
|
||||
m_timeAccumulator = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualConsole::handleEvents(void)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
if (event.type == SDL_QUIT) exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualConsole::finalizeRender(void)
|
||||
{
|
||||
SDL_RenderClear(m_renderer);
|
||||
SDL_UpdateTexture(m_screenTexture, NULL, m_screenPixels, m_windowWidth * 4);
|
||||
SDL_RenderCopy(m_renderer, m_screenTexture, NULL, NULL);
|
||||
SDL_RenderPresent(m_renderer);
|
||||
}
|
||||
|
||||
void VirtualConsole::drawConsole(void)
|
||||
{
|
||||
const uint8_t TRANSPARENCY_COLOR_INDEX = 0x5;
|
||||
|
||||
uint8_t clearColor = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::ClearColor);
|
||||
uint8_t palette = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::Palette);
|
||||
bool useTransparency = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::UseTransparencyOn0x5) != 0;
|
||||
|
||||
if (palette >= m_palettes.size())
|
||||
palette = 0; //TODO: Error
|
||||
|
||||
auto& pal = *m_palettes[palette];
|
||||
|
||||
ostd::Color clrCol = pal.getColor(clearColor);
|
||||
if (m_clearMemory)
|
||||
{
|
||||
for (int y = 0; y < m_windowHeight; ++y)
|
||||
{
|
||||
for (int x = 0; x < m_windowWidth; ++x)
|
||||
{
|
||||
m_screenPixels[x + y * m_windowWidth] = clrCol.asInteger();
|
||||
}
|
||||
}
|
||||
m_clearMemory = false;
|
||||
}
|
||||
|
||||
ostd::Color fgCol;
|
||||
ostd::Color bgCol;
|
||||
uint16_t index = hw::VirtualBIOSVideo::tRegisters::VideoMemoryStart;
|
||||
|
||||
// if (m_clearMemory)
|
||||
// {
|
||||
// for (int32_t i = index; i < (index + (RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * 2)); i += 2)
|
||||
// {
|
||||
// m_biosVideo.write8((uint16_t)i, 0x00);
|
||||
// m_biosVideo.write8((uint16_t)(i + 1), clearColor);
|
||||
// }
|
||||
// m_clearMemory = false;
|
||||
// }
|
||||
|
||||
for (int32_t i = index; i < (index + (RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * 2)); i += 2)
|
||||
{
|
||||
uint8_t character = m_biosVideo.read8((uint16_t)i);
|
||||
uint8_t colors = m_biosVideo.read8((uint16_t)(i + 1));
|
||||
uint8_t bgcol = (colors >> 4) & 0xF;
|
||||
uint8_t fgcol = (colors & 0xF);
|
||||
if (!isprint(character))
|
||||
{
|
||||
character = ' ';
|
||||
fgCol = pal.getColor(fgcol);
|
||||
bgCol = clrCol;
|
||||
}
|
||||
else
|
||||
{
|
||||
fgCol = pal.getColor(fgcol);
|
||||
bgCol = pal.getColor(bgcol);
|
||||
}
|
||||
vout.bgcol(bgCol).col(fgCol).p((char)character).flush().bgcol(clrCol);
|
||||
}
|
||||
vout.refreshScreen();
|
||||
m_cpu.handleInterrupt(data::InterruptCodes::BiosVideoScreenRefresh);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../tools/SDLInclude.hpp"
|
||||
|
||||
#include <ostd/Utils.hpp>
|
||||
#include "VirtualConsoleOutputHandler.hpp"
|
||||
#include "../tools/GlobalData.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
class VirtualBIOSVideo;
|
||||
class VirtualCPU;
|
||||
}
|
||||
class VirtualConsole
|
||||
{
|
||||
public: struct tSignals
|
||||
{
|
||||
inline static constexpr uint8_t Continue = 0x00;
|
||||
inline static constexpr uint8_t ClearScreen = 0x01;
|
||||
};
|
||||
|
||||
public:
|
||||
inline VirtualConsole(hw::VirtualBIOSVideo& biosVideo, hw::VirtualCPU& cpu) : m_biosVideo(biosVideo), m_cpu(cpu) { }
|
||||
inline bool isInitialized(void) const { return m_initialized; }
|
||||
inline bool isRunning(void) const { return m_running; }
|
||||
void initialize(void);
|
||||
void update(void);
|
||||
|
||||
private:
|
||||
void handleEvents(void);
|
||||
void finalizeRender(void);
|
||||
void drawConsole(void);
|
||||
|
||||
private:
|
||||
ostd::ConsoleOutputHandler out;
|
||||
dragon::VirtualConsoleOutputHandler vout;
|
||||
|
||||
SDL_Window* m_window { nullptr };
|
||||
SDL_Renderer* m_renderer { nullptr };
|
||||
SDL_Texture* m_screenTexture { nullptr };
|
||||
SDL_Surface* m_fontSurface { nullptr };
|
||||
|
||||
int32_t m_windowWidth { 0 };
|
||||
int32_t m_windowHeight { 0 };
|
||||
|
||||
uint32_t* m_fontPixels { nullptr };
|
||||
uint32_t* m_screenPixels { nullptr };
|
||||
|
||||
bool m_redrawConsole { true };
|
||||
float m_timeAccumulator { 0.0f };
|
||||
bool m_running { false };
|
||||
|
||||
ostd::StringEditor m_title { "" };
|
||||
float m_redrawAccumulator { 0.0f };
|
||||
bool m_initialized { false };
|
||||
bool m_clearMemory { false };
|
||||
|
||||
hw::VirtualBIOSVideo& m_biosVideo;
|
||||
hw::VirtualCPU& m_cpu;
|
||||
std::vector<data::IBiosVideoPalette*> m_palettes;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,303 +0,0 @@
|
|||
#include "VirtualConsoleOutputHandler.hpp"
|
||||
#include "RawTextRenderer.hpp"
|
||||
|
||||
#include <ostd/Defines.hpp>
|
||||
#include <ostd/Logger.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
tRichChar RichString::at(uint32_t index) const
|
||||
{
|
||||
if (index >= m_text.size())
|
||||
{
|
||||
OX_WARN("ox::RichString::at(...): Index out of bounds.");
|
||||
return tRichChar();
|
||||
}
|
||||
return { (unsigned char)m_text[index], m_foreground[index], m_background[index] };
|
||||
}
|
||||
|
||||
void RichString::add(tRichChar rchar)
|
||||
{
|
||||
m_text += rchar.ascii;
|
||||
m_foreground.push_back(rchar.foreground);
|
||||
m_background.push_back(rchar.background);
|
||||
}
|
||||
|
||||
void RichString::add(ostd::String str, ostd::Color fg, ostd::Color bg)
|
||||
{
|
||||
for (auto& c : str)
|
||||
{
|
||||
m_text += c;
|
||||
m_foreground.push_back(fg);
|
||||
m_background.push_back(bg);
|
||||
}
|
||||
}
|
||||
|
||||
void RichString::add(ostd::String str)
|
||||
{
|
||||
ostd::Color fcol(255);
|
||||
ostd::Color bcol(0, 0);
|
||||
if (m_text.length() > 0)
|
||||
{
|
||||
fcol = m_foreground[m_foreground.size() - 1];
|
||||
bcol = m_background[m_background.size() - 1];
|
||||
}
|
||||
add(str, fcol, bcol);
|
||||
}
|
||||
|
||||
void RichString::clear(void)
|
||||
{
|
||||
m_text = "";
|
||||
m_background.clear();
|
||||
m_foreground.clear();
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::col(ostd::String color)
|
||||
{
|
||||
//TODO: Maybe implement??
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::col(const ostd::Color& color)
|
||||
{
|
||||
m_currentForegroundColor = color;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::p(char c)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.add(c);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::p(const ostd::StringEditor& se)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.add(se.str());
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(uint8_t i)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addi(i);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(int8_t i)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addi(i);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(uint16_t i)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addi(i);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(int16_t i)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addi(i);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(uint32_t i)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addi(i);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(int32_t i)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addi(i);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(uint64_t i)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addi(i);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(int64_t i)
|
||||
{
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addi(i);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pf(float f, uint8_t precision)
|
||||
{
|
||||
//TODO: Implement precision
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addf(f);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pf(double f, uint8_t precision)
|
||||
{
|
||||
//TODO: Implement precision
|
||||
check_if_new_line();
|
||||
m_currentBufferEditor.addf(f);
|
||||
add_current_to_rich_buffer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::nl(void)
|
||||
{
|
||||
m_newLine = true;
|
||||
flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::flush(void)
|
||||
{
|
||||
if (!isInitialized()) return *this;
|
||||
if (m_currentBuffer.getText() == "") return *this;
|
||||
|
||||
m_lines.push_back(m_currentBuffer);
|
||||
m_currentBuffer.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::reset(void)
|
||||
{
|
||||
m_currentBuffer.clear();
|
||||
m_currentBufferEditor.clr();
|
||||
m_lines.clear();
|
||||
m_newLine = true;
|
||||
resetColors();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::clear(void)
|
||||
{
|
||||
//TODO: Implement
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::bgcol(const ostd::Color& color)
|
||||
{
|
||||
m_currentBackgroundColor = color;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::bgcol(ostd::String color)
|
||||
{
|
||||
//TODO: Maybe implement
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::resetColors(void)
|
||||
{
|
||||
m_currentForegroundColor = m_defaultForegroundColor;
|
||||
m_currentBackgroundColor = m_defaultBackgroundColor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void VirtualConsoleOutputHandler::init(uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels)
|
||||
{
|
||||
m_screenPixels = screenPixels;
|
||||
m_fontPixels = fontPixels;
|
||||
m_screenHeight = screenHeight;
|
||||
m_screenWidth = screenWidth;
|
||||
|
||||
m_initialized = m_screenHeight > 0 && m_screenWidth > 0 && m_screenPixels != nullptr && m_fontPixels != nullptr;
|
||||
}
|
||||
|
||||
void VirtualConsoleOutputHandler::add_current_to_rich_buffer(void)
|
||||
{
|
||||
if (m_currentBuffer.getText().length() + m_currentBufferEditor.len() <= RawTextRenderer::CONSOLE_CHARS_H)
|
||||
{
|
||||
m_currentBuffer.add(m_currentBufferEditor.str(), m_currentForegroundColor, m_currentBackgroundColor);
|
||||
m_currentBufferEditor.clr();
|
||||
if (m_currentBuffer.getText().length() == RawTextRenderer::CONSOLE_CHARS_H)
|
||||
nl();
|
||||
else
|
||||
m_newLine = false;
|
||||
return;
|
||||
}
|
||||
int32_t extraStringLength = (m_currentBuffer.getText().length() + m_currentBufferEditor.len()) - RawTextRenderer::CONSOLE_CHARS_H;
|
||||
ostd::String excess = m_currentBufferEditor.substr(RawTextRenderer::CONSOLE_CHARS_H);
|
||||
ostd::String end = m_currentBufferEditor.substr(0, RawTextRenderer::CONSOLE_CHARS_H);
|
||||
m_currentBuffer.add(end, m_currentForegroundColor, m_currentBackgroundColor);
|
||||
nl();
|
||||
m_currentBufferEditor = excess;
|
||||
add_current_to_rich_buffer();
|
||||
}
|
||||
|
||||
void VirtualConsoleOutputHandler::check_if_new_line(void)
|
||||
{
|
||||
if (m_newLine) return;
|
||||
if (m_lines.size() > 0)
|
||||
{
|
||||
m_currentBuffer = m_lines[m_lines.size() - 1];
|
||||
m_lines.pop_back();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VirtualConsoleOutputHandler::draw_rich_String(const RichString& rstr, uint32_t row)
|
||||
{
|
||||
for (int32_t i = 0; i < rstr.getText().length(); i++)
|
||||
{
|
||||
auto rchar = rstr.at(i);
|
||||
RawTextRenderer::drawString(ostd::StringEditor().add(rchar.ascii).str(), i, row, m_screenPixels, m_screenWidth, m_screenHeight, m_fontPixels, rchar.foreground, rchar.background);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualConsoleOutputHandler::refreshScreen(void)
|
||||
{
|
||||
uint32_t row = 0;
|
||||
if (m_lines.size() > RawTextRenderer::CONSOLE_CHARS_V - 1)
|
||||
{
|
||||
if (m_fixedScreen)
|
||||
{
|
||||
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V; i++)
|
||||
{
|
||||
draw_rich_String(m_lines[i], row);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int32_t i = m_lines.size() - RawTextRenderer::CONSOLE_CHARS_V + 1; i < m_lines.size(); i++)
|
||||
{
|
||||
draw_rich_String(m_lines[i], row);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& line : m_lines)
|
||||
{
|
||||
draw_rich_String(line, row);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
m_lines.clear();
|
||||
m_currentBuffer.clear();
|
||||
m_currentBufferEditor.clr();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <ostd/Color.hpp>
|
||||
|
||||
#include <ostd/IOHandlers.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
struct tRichChar
|
||||
{
|
||||
unsigned char ascii { 0 };
|
||||
ostd::Color foreground { 0, 0 };
|
||||
ostd::Color background { 0, 0 };
|
||||
};
|
||||
|
||||
class RichString //TODO: Legacy RichString should be replaced with new tStyledString
|
||||
{
|
||||
public:
|
||||
inline RichString(void) { }
|
||||
inline ostd::String getText(void) const { return m_text; }
|
||||
tRichChar at(uint32_t index) const;
|
||||
void add(tRichChar rchar);
|
||||
void add(ostd::String str, ostd::Color fg, ostd::Color bg);
|
||||
void add(ostd::String str);
|
||||
void clear(void);
|
||||
|
||||
private:
|
||||
ostd::String m_text { "" };
|
||||
std::vector<ostd::Color> m_foreground;
|
||||
std::vector<ostd::Color> m_background;
|
||||
};
|
||||
|
||||
class VirtualConsoleOutputHandler : public ostd::legacy::IOutputHandler
|
||||
{
|
||||
public:
|
||||
ostd::legacy::IOutputHandler& col(ostd::String color) override;
|
||||
ostd::legacy::IOutputHandler& col(const ostd::Color& color) override;
|
||||
ostd::legacy::IOutputHandler& p(char c) override;
|
||||
ostd::legacy::IOutputHandler& p(const ostd::StringEditor& se) override;
|
||||
ostd::legacy::IOutputHandler& pi(uint8_t i) override;
|
||||
ostd::legacy::IOutputHandler& pi(int8_t i) override;
|
||||
ostd::legacy::IOutputHandler& pi(uint16_t i) override;
|
||||
ostd::legacy::IOutputHandler& pi(int16_t i) override;
|
||||
ostd::legacy::IOutputHandler& pi(uint32_t i) override;
|
||||
ostd::legacy::IOutputHandler& pi(int32_t i) override;
|
||||
ostd::legacy::IOutputHandler& pi(uint64_t i) override;
|
||||
ostd::legacy::IOutputHandler& pi(int64_t i) override;
|
||||
ostd::legacy::IOutputHandler& pf(float f, uint8_t precision = 0) override;
|
||||
ostd::legacy::IOutputHandler& pf(double f, uint8_t precision = 0) override;
|
||||
ostd::legacy::IOutputHandler& nl(void) override;
|
||||
inline ostd::legacy::IOutputHandler& pStyled(const ostd::StringEditor& styled) override { return *this; } //TODO: Implement
|
||||
inline ostd::legacy::IOutputHandler& pStyled(const ostd::TextStyleBuilder::IRichStringBase& styled) override { return *this; } //TODO: Implement
|
||||
inline ostd::legacy::IOutputHandler& pStyled(const ostd::TextStyleParser::tStyledString& styled) override { return *this; }; //TODO: Implement
|
||||
ostd::legacy::IOutputHandler& flush(void) override;
|
||||
ostd::legacy::IOutputHandler& reset(void) override;
|
||||
ostd::legacy::IOutputHandler& clear(void) override;
|
||||
|
||||
ostd::legacy::IOutputHandler& bgcol(const ostd::Color& color) override;
|
||||
ostd::legacy::IOutputHandler& bgcol(ostd::String color) override;
|
||||
ostd::legacy::IOutputHandler& resetColors(void) override;
|
||||
|
||||
void init(uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels);
|
||||
inline bool isInitialized(void) const { return m_initialized; }
|
||||
inline bool isFixedScreen(void) const { return m_fixedScreen; }
|
||||
inline void enableFixedScreen(bool fs = true) { m_fixedScreen = fs; }
|
||||
|
||||
void refreshScreen(void);
|
||||
|
||||
private:
|
||||
void add_current_to_rich_buffer(void);
|
||||
void check_if_new_line(void);
|
||||
void draw_rich_String(const RichString& rstr, uint32_t row);
|
||||
|
||||
private:
|
||||
std::vector<RichString> m_lines;
|
||||
RichString m_currentBuffer;
|
||||
ostd::StringEditor m_currentBufferEditor;
|
||||
|
||||
// std::vector<ostd::String> m_allLines;
|
||||
// ostd::StringEditor m_buffer;
|
||||
// int32_t m_currentRow { 0 };
|
||||
// int32_t m_currentColumn { 0 };
|
||||
ostd::Color m_currentForegroundColor { 255, 255, 255, 255 };
|
||||
ostd::Color m_currentBackgroundColor { 255, 255, 255, 0 };
|
||||
ostd::Color m_defaultForegroundColor { 255, 255, 255, 255 };
|
||||
ostd::Color m_defaultBackgroundColor { 255, 255, 255, 0 };
|
||||
|
||||
uint32_t* m_screenPixels { nullptr };
|
||||
uint32_t* m_fontPixels { nullptr };
|
||||
int32_t m_screenWidth { 0 };
|
||||
int32_t m_screenHeight { 0 };
|
||||
bool m_initialized { false };
|
||||
bool m_newLine { true };
|
||||
bool m_fixedScreen { false };
|
||||
};
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
#include "Window.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
void Window::initialize(int32_t width, int32_t height, const ostd::String& fontPath)
|
||||
{
|
||||
m_windowWidth = width;
|
||||
m_windowHeight = height;
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
m_window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_windowWidth, m_windowHeight, SDL_WINDOW_RESIZABLE);
|
||||
SDL_SetWindowResizable(m_window, SDL_FALSE);
|
||||
m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight);
|
||||
// m_screenTexture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, m_windowWidth, m_windowHeight);
|
||||
m_fontSurface = SDL_LoadBMP(fontPath.c_str());
|
||||
if (m_fontSurface == NULL)
|
||||
out.bg(ostd::ConsoleColors::Red).p("Error loading font.").reset().nl();
|
||||
m_fontPixels = (uint32_t*)m_fontSurface->pixels;
|
||||
// m_screenPixels = (uint32_t*)malloc(m_windowWidth * m_windowHeight * 4);
|
||||
|
||||
m_initialized = true;
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
void Window::update(void)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
Uint64 start = SDL_GetPerformanceCounter();
|
||||
handleEvents();
|
||||
SDL_RenderClear(m_renderer);
|
||||
for (int32_t i = 0; i < m_widgets.size(); i++)
|
||||
{
|
||||
if (m_widgets[i] == nullptr) continue;
|
||||
m_widgets[i]->draw();
|
||||
}
|
||||
SDL_RenderPresent(m_renderer);
|
||||
// finalizeRender();
|
||||
Uint64 end = SDL_GetPerformanceCounter();
|
||||
float elapsed = (end - start) / (float)SDL_GetPerformanceFrequency();
|
||||
m_redrawAccumulator += elapsed;
|
||||
if (m_redrawAccumulator >= 0.2f)
|
||||
{
|
||||
for (int32_t i = 0; i < m_widgets.size(); i++)
|
||||
{
|
||||
if (m_widgets[i] == nullptr) continue;
|
||||
m_widgets[i]->fixedUpdate();
|
||||
}
|
||||
m_redrawAccumulator = 0.0f;
|
||||
}
|
||||
end = SDL_GetPerformanceCounter();
|
||||
elapsed = (end - start) / (float)SDL_GetPerformanceFrequency();
|
||||
m_timeAccumulator += elapsed;
|
||||
if (m_timeAccumulator >= 0.5f)
|
||||
{
|
||||
for (int32_t i = 0; i < m_widgets.size(); i++)
|
||||
{
|
||||
if (m_widgets[i] == nullptr) continue;
|
||||
m_widgets[i]->slowUpdate();
|
||||
}
|
||||
m_title.clr().add("FPS: ").addi((int)(1.0f / elapsed));
|
||||
SDL_SetWindowTitle(m_window, m_title.c_str());
|
||||
m_timeAccumulator = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bool Window::addWidget(Widget& widget)
|
||||
{
|
||||
widget.__init(*this);
|
||||
m_widgets.push_back(&widget);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::setSize(int32_t width, int32_t height)
|
||||
{
|
||||
if (!isInitialized()) return;
|
||||
SDL_SetWindowSize(m_window, width, height);
|
||||
}
|
||||
|
||||
void Window::handleEvents(void)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
if (event.type == SDL_QUIT)
|
||||
{
|
||||
m_running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Window::finalizeRender(void)
|
||||
{
|
||||
// SDL_UpdateTexture(m_screenTexture, NULL, m_screenPixels, m_windowWidth * 4);
|
||||
// SDL_RenderCopy(m_renderer, m_screenTexture, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../tools/SDLInclude.hpp"
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <ostd/Signals.hpp>
|
||||
#include "VirtualConsoleOutputHandler.hpp"
|
||||
#include "../tools/GlobalData.hpp"
|
||||
#include "../gui/widgets/Widget.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
inline Window(void) { }
|
||||
inline bool isInitialized(void) const { return m_initialized; }
|
||||
inline bool isRunning(void) const { return m_running; }
|
||||
inline void hide(void) { SDL_HideWindow(m_window); }
|
||||
inline void show(void) { SDL_ShowWindow(m_window); }
|
||||
void initialize(int32_t width, int32_t height, const ostd::String& fontPath);
|
||||
void update(void);
|
||||
bool addWidget(Widget& widget);
|
||||
void setSize(int32_t width, int32_t height);
|
||||
|
||||
private:
|
||||
void handleEvents(void);
|
||||
void finalizeRender(void);
|
||||
|
||||
private:
|
||||
ostd::ConsoleOutputHandler out;
|
||||
|
||||
std::vector<Widget*> m_widgets;
|
||||
|
||||
SDL_Window* m_window { nullptr };
|
||||
SDL_Renderer* m_renderer { nullptr };
|
||||
// SDL_Texture* m_screenTexture { nullptr };
|
||||
SDL_Surface* m_fontSurface { nullptr };
|
||||
|
||||
int32_t m_windowWidth { 0 };
|
||||
int32_t m_windowHeight { 0 };
|
||||
|
||||
uint32_t* m_fontPixels { nullptr };
|
||||
// uint32_t* m_screenPixels { nullptr };
|
||||
|
||||
float m_timeAccumulator { 0.0f };
|
||||
bool m_running { false };
|
||||
|
||||
ostd::StringEditor m_title { "" };
|
||||
float m_redrawAccumulator { 0.0f };
|
||||
bool m_initialized { false };
|
||||
|
||||
//Signals
|
||||
inline static const uint32_t Signal_OnMousePressed = ostd::SignalHandler::newCustomSignal(4096);
|
||||
|
||||
friend class VirtualConsoleWidtget;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
#include "VirtualConsoleWidget.hpp"
|
||||
#include "../../gui/RawTextRenderer.hpp"
|
||||
#include "../../gui/Window.hpp"
|
||||
#include "../../hardware/VirtualIODevices.hpp"
|
||||
#include "../../hardware/VirtualCPU.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
void VirtualConsoleWidtget::init(void)
|
||||
{
|
||||
setw(RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::FONT_CHAR_W); //60 * 16;
|
||||
seth(RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::FONT_CHAR_H); //60 * 9;
|
||||
setPosition(0, 0);
|
||||
|
||||
dragon::RawTextRenderer::initialize();
|
||||
|
||||
m_pixels = new uint32_t[getw() * geth()]; //TODO: Delete (Memory Leak)
|
||||
|
||||
vout.init(m_pixels, getw(), geth(), m_parent->m_fontPixels);
|
||||
vout.enableFixedScreen();
|
||||
|
||||
m_palettes.push_back(new data::BiosVideoDefaultPalette); //TODO: Possible Memory Leak, palettes are never destroyed
|
||||
|
||||
m_texture = SDL_CreateTexture(m_parent->m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, getw(), geth());
|
||||
|
||||
m_initialized = true;
|
||||
validate();
|
||||
}
|
||||
|
||||
void VirtualConsoleWidtget::draw(void)
|
||||
{
|
||||
if (isInvalid()) return;
|
||||
SDL_Rect rect { (int)getx(), (int)gety(), (int)getw(), (int)geth() };
|
||||
SDL_RenderCopy(m_parent->m_renderer, m_texture, NULL, &rect);
|
||||
}
|
||||
|
||||
void VirtualConsoleWidtget::drawConsole(void)
|
||||
{
|
||||
if (isInvalid()) return;
|
||||
const uint8_t TRANSPARENCY_COLOR_INDEX = 0x5;
|
||||
|
||||
uint8_t clearColor = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::ClearColor);
|
||||
uint8_t palette = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::Palette);
|
||||
bool useTransparency = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::UseTransparencyOn0x5) != 0;
|
||||
|
||||
if (palette >= m_palettes.size())
|
||||
palette = 0; //TODO: Error
|
||||
|
||||
auto& pal = *m_palettes[palette];
|
||||
|
||||
ostd::Color clrCol = pal.getColor(clearColor);
|
||||
if (m_clearMemory)
|
||||
{
|
||||
for (int y = 0; y < m_parent->m_windowHeight; ++y)
|
||||
{
|
||||
for (int x = 0; x < m_parent->m_windowWidth; ++x)
|
||||
{
|
||||
m_pixels[x + y * m_parent->m_windowWidth] = clrCol.asInteger();
|
||||
}
|
||||
}
|
||||
m_clearMemory = false;
|
||||
}
|
||||
|
||||
ostd::Color fgCol;
|
||||
ostd::Color bgCol;
|
||||
uint16_t index = hw::VirtualBIOSVideo::tRegisters::VideoMemoryStart;
|
||||
|
||||
// if (m_clearMemory)
|
||||
// {
|
||||
// for (int32_t i = index; i < (index + (RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * 2)); i += 2)
|
||||
// {
|
||||
// m_biosVideo.write8((uint16_t)i, 0x00);
|
||||
// m_biosVideo.write8((uint16_t)(i + 1), clearColor);
|
||||
// }
|
||||
// m_clearMemory = false;
|
||||
// }
|
||||
|
||||
for (int32_t i = index; i < (index + (RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * 2)); i += 2)
|
||||
{
|
||||
uint8_t character = m_biosVideo.read8((uint16_t)i);
|
||||
uint8_t colors = m_biosVideo.read8((uint16_t)(i + 1));
|
||||
uint8_t bgcol = (colors >> 4) & 0xF;
|
||||
uint8_t fgcol = (colors & 0xF);
|
||||
if (!isprint(character))
|
||||
{
|
||||
character = ' ';
|
||||
fgCol = pal.getColor(fgcol);
|
||||
bgCol = clrCol;
|
||||
}
|
||||
else
|
||||
{
|
||||
fgCol = pal.getColor(fgcol);
|
||||
bgCol = pal.getColor(bgcol);
|
||||
}
|
||||
vout.bgcol(bgCol).col(fgCol).p((char)character).flush().bgcol(clrCol);
|
||||
}
|
||||
vout.refreshScreen();
|
||||
m_cpu.handleInterrupt(data::InterruptCodes::BiosVideoScreenRefresh);
|
||||
}
|
||||
|
||||
void VirtualConsoleWidtget::update(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void VirtualConsoleWidtget::fixedUpdate(void)
|
||||
{
|
||||
if (isInvalid()) return;
|
||||
uint8_t signal = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::Signal);
|
||||
switch (signal)
|
||||
{
|
||||
case tSignals::ClearScreen:
|
||||
m_clearMemory = true;
|
||||
break;
|
||||
case tSignals::Continue: break;
|
||||
default: break;
|
||||
}
|
||||
m_biosVideo.write8(hw::VirtualBIOSVideo::tRegisters::Signal, tSignals::Continue);
|
||||
drawConsole();
|
||||
SDL_UpdateTexture(m_texture, NULL, m_pixels, getw() * 4);
|
||||
}
|
||||
|
||||
void VirtualConsoleWidtget::slowUpdate(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.hpp"
|
||||
|
||||
#include "../../tools/SDLInclude.hpp"
|
||||
|
||||
#include "../../gui/VirtualConsoleOutputHandler.hpp"
|
||||
#include "../../tools/GlobalData.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
class VirtualBIOSVideo;
|
||||
class VirtualCPU;
|
||||
}
|
||||
class VirtualConsoleWidtget : public Widget
|
||||
{
|
||||
public: struct tSignals
|
||||
{
|
||||
inline static constexpr uint8_t Continue = 0x00;
|
||||
inline static constexpr uint8_t ClearScreen = 0x01;
|
||||
};
|
||||
public:
|
||||
inline VirtualConsoleWidtget(hw::VirtualBIOSVideo& biosVideo, hw::VirtualCPU& cpu) : m_biosVideo(biosVideo), m_cpu(cpu) { invalidate(); }
|
||||
void init(void) override;
|
||||
void draw(void) override;
|
||||
void update(void) override;
|
||||
void fixedUpdate(void) override;
|
||||
void slowUpdate(void) override;
|
||||
|
||||
inline bool isInitialized(void) const { return m_initialized; }
|
||||
|
||||
private:
|
||||
void drawConsole(void);
|
||||
|
||||
private:
|
||||
dragon::VirtualConsoleOutputHandler vout;
|
||||
|
||||
// SDL_Window* m_window { nullptr };
|
||||
// SDL_Renderer* m_renderer { nullptr };
|
||||
// SDL_Texture* m_screenTexture { nullptr };
|
||||
// SDL_Surface* m_fontSurface { nullptr };
|
||||
|
||||
// int32_t m_windowWidth { 0 };
|
||||
// int32_t m_windowHeight { 0 };
|
||||
|
||||
// uint32_t* m_fontPixels { nullptr };
|
||||
// uint32_t* m_screenPixels { nullptr };
|
||||
|
||||
uint32_t* m_pixels { nullptr };
|
||||
SDL_Texture* m_texture;
|
||||
|
||||
// bool m_redrawConsole { true };
|
||||
// float m_timeAccumulator { 0.0f };
|
||||
// bool m_running { false };
|
||||
|
||||
// ostd::StringEditor m_title { "" };
|
||||
// float m_redrawAccumulator { 0.0f };
|
||||
bool m_initialized { false };
|
||||
bool m_clearMemory { false };
|
||||
|
||||
hw::VirtualBIOSVideo& m_biosVideo;
|
||||
hw::VirtualCPU& m_cpu;
|
||||
std::vector<data::IBiosVideoPalette*> m_palettes;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <ostd/Geometry.hpp>
|
||||
#include <ostd/BaseObject.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
class Window;
|
||||
class Widget : public ostd::Rectangle, public ostd::BaseObject
|
||||
{
|
||||
public:
|
||||
void __init(Window& parent) { m_parent = &parent; init(); }
|
||||
virtual void draw(void) { }
|
||||
virtual void update(void) { }
|
||||
virtual void fixedUpdate(void) { }
|
||||
virtual void slowUpdate(void) { }
|
||||
|
||||
protected:
|
||||
virtual void init(void) { }
|
||||
|
||||
protected:
|
||||
Window* m_parent { nullptr };
|
||||
};
|
||||
}
|
||||
753
src/hardware/CPUExtensions.cpp
Normal file
|
|
@ -0,0 +1,753 @@
|
|||
#include "CPUExtensions.hpp"
|
||||
#include "VirtualCPU.hpp"
|
||||
#include "../runtime/DragonRuntime.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
namespace cpuext
|
||||
{
|
||||
String ExtMov::getOpCodeString(u8 opCode)
|
||||
{
|
||||
switch (opCode)
|
||||
{
|
||||
case OpCodes::wimm_in_dreg_immoffw: return m_name + "_wimm_in_dreg_immoffw";
|
||||
case OpCodes::wimm_in_dreg_regoff: return m_name + "_wimm_in_dreg_regoff";
|
||||
case OpCodes::wimm_in_dreg_immoffb: return m_name + "_wimm_in_dreg_immoffb";
|
||||
case OpCodes::bimm_in_dreg_immoffw: return m_name + "_bimm_in_dreg_immoffw";
|
||||
case OpCodes::bimm_in_dreg_regoff: return m_name + "_bimm_in_dreg_regoff";
|
||||
case OpCodes::bimm_in_dreg_immoffb: return m_name + "_bimm_in_dreg_immoffb";
|
||||
case OpCodes::wdreg_in_dreg_immoffw: return m_name + "_wdreg_in_dreg_immoffw";
|
||||
case OpCodes::wdreg_in_dreg_regoff: return m_name + "_wdreg_in_dreg_regoff";
|
||||
case OpCodes::wdreg_in_dreg_immoffb: return m_name + "_wdreg_in_dreg_immoffb";
|
||||
case OpCodes::bdreg_in_dreg_immoffw: return m_name + "_bdreg_in_dreg_immoffw";
|
||||
case OpCodes::bdreg_in_dreg_regoff: return m_name + "_bdreg_in_dreg_regoff";
|
||||
case OpCodes::bdreg_in_dreg_immoffb: return m_name + "_bdreg_in_dreg_immoffb";
|
||||
case OpCodes::wimm_in_mem_immoffw: return m_name + "_wimm_in_mem_immoffw";
|
||||
case OpCodes::wimm_in_mem_regoff: return m_name + "_wimm_in_mem_regoff";
|
||||
case OpCodes::wimm_in_mem_immoffb: return m_name + "_wimm_in_mem_immoffb";
|
||||
case OpCodes::bimm_in_mem_immoffw: return m_name + "_bimm_in_mem_immoffw";
|
||||
case OpCodes::bimm_in_mem_regoff: return m_name + "_bimm_in_mem_regoff";
|
||||
case OpCodes::bimm_in_mem_immoffb: return m_name + "_bimm_in_mem_immoffb";
|
||||
case OpCodes::wdreg_immoffw_in_dreg: return m_name + "_wdreg_immoffw_in_dreg";
|
||||
case OpCodes::wdreg_regoff_in_dreg: return m_name + "_wdreg_regoff_in_dreg";
|
||||
case OpCodes::wdreg_immoffb_in_dreg: return m_name + "_wdreg_immoffb_in_dreg";
|
||||
case OpCodes::bdreg_immoffw_in_dreg: return m_name + "_bdreg_immoffw_in_dreg";
|
||||
case OpCodes::bdreg_regoff_in_dreg: return m_name + "_bdreg_regoff_in_dreg";
|
||||
case OpCodes::bdreg_immoffb_in_dreg: return m_name + "_bdreg_immoffb_in_dreg";
|
||||
case OpCodes::wmem_immoffw_in_reg: return m_name + "_wmem_immoffw_in_reg";
|
||||
case OpCodes::wmem_regoff_in_reg: return m_name + "_wmem_regoff_in_reg";
|
||||
case OpCodes::wmem_immoffb_in_reg: return m_name + "_wmem_immoffb_in_reg";
|
||||
case OpCodes::bmem_immoffw_in_reg: return m_name + "_bmem_immoffw_in_reg";
|
||||
case OpCodes::bmem_regoff_in_reg: return m_name + "_bmem_regoff_in_reg";
|
||||
case OpCodes::bmem_immoffb_in_reg: return m_name + "_bmem_immoffb_in_reg";
|
||||
case OpCodes::wdreg_immoffw_in_reg: return m_name + "_wdreg_immoffw_in_reg";
|
||||
case OpCodes::wdreg_regoff_in_reg: return m_name + "_wdreg_regoff_in_reg";
|
||||
case OpCodes::wdreg_immoffb_in_reg: return m_name + "_wdreg_immoffb_in_reg";
|
||||
case OpCodes::bdreg_immoffw_in_reg: return m_name + "_bdreg_immoffw_in_reg";
|
||||
case OpCodes::bdreg_regoff_in_reg: return m_name + "_bdreg_regoff_in_reg";
|
||||
case OpCodes::bdreg_immoffb_in_reg: return m_name + "_bdreg_immoffb_in_reg";
|
||||
default: return m_name + "_UNKNOWN_INST";
|
||||
}
|
||||
}
|
||||
|
||||
u8 ExtMov::getInstructionSIze(u8 opCode)
|
||||
{
|
||||
switch (opCode)
|
||||
{
|
||||
case OpCodes::wimm_in_dreg_immoffw: return 6;
|
||||
case OpCodes::wimm_in_dreg_regoff: return 5;
|
||||
case OpCodes::wimm_in_dreg_immoffb: return 5;
|
||||
case OpCodes::bimm_in_dreg_immoffw: return 5;
|
||||
case OpCodes::bimm_in_dreg_regoff: return 4;
|
||||
case OpCodes::bimm_in_dreg_immoffb: return 4;
|
||||
case OpCodes::wdreg_in_dreg_immoffw: return 5;
|
||||
case OpCodes::wdreg_in_dreg_regoff: return 4;
|
||||
case OpCodes::wdreg_in_dreg_immoffb: return 4;
|
||||
case OpCodes::bdreg_in_dreg_immoffw: return 5;
|
||||
case OpCodes::bdreg_in_dreg_regoff: return 4;
|
||||
case OpCodes::bdreg_in_dreg_immoffb: return 4;
|
||||
case OpCodes::wimm_in_mem_immoffw: return 7;
|
||||
case OpCodes::wimm_in_mem_regoff: return 6;
|
||||
case OpCodes::wimm_in_mem_immoffb: return 6;
|
||||
case OpCodes::bimm_in_mem_immoffw: return 6;
|
||||
case OpCodes::bimm_in_mem_regoff: return 5;
|
||||
case OpCodes::bimm_in_mem_immoffb: return 5;
|
||||
case OpCodes::wdreg_immoffw_in_dreg: return 5;
|
||||
case OpCodes::wdreg_regoff_in_dreg: return 4;
|
||||
case OpCodes::wdreg_immoffb_in_dreg: return 4;
|
||||
case OpCodes::bdreg_immoffw_in_dreg: return 5;
|
||||
case OpCodes::bdreg_regoff_in_dreg: return 4;
|
||||
case OpCodes::bdreg_immoffb_in_dreg: return 4;
|
||||
case OpCodes::wmem_immoffw_in_reg: return 6;
|
||||
case OpCodes::wmem_regoff_in_reg: return 5;
|
||||
case OpCodes::wmem_immoffb_in_reg: return 5;
|
||||
case OpCodes::bmem_immoffw_in_reg: return 6;
|
||||
case OpCodes::bmem_regoff_in_reg: return 5;
|
||||
case OpCodes::bmem_immoffb_in_reg: return 5;
|
||||
case OpCodes::wdreg_immoffw_in_reg: return 5;
|
||||
case OpCodes::wdreg_regoff_in_reg: return 4;
|
||||
case OpCodes::wdreg_immoffb_in_reg: return 4;
|
||||
case OpCodes::bdreg_immoffw_in_reg: return 5;
|
||||
case OpCodes::bdreg_regoff_in_reg: return 4;
|
||||
case OpCodes::bdreg_immoffb_in_reg: return 4;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ExtMov::execute(VirtualCPU& vcpu)
|
||||
{
|
||||
auto& mem = DragonRuntime::memMap;
|
||||
u8 inst = vcpu.fetch8();
|
||||
switch (inst)
|
||||
{
|
||||
case OpCodes::wimm_in_dreg_immoffw:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_wimm = vcpu.fetch16();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write16(dest_mem + offset, src_wimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::wimm_in_dreg_regoff:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_wimm = vcpu.fetch16();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write16(dest_mem + offset, src_wimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::wimm_in_dreg_immoffb:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_wimm = vcpu.fetch16();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write16(dest_mem + offset, src_wimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::bimm_in_dreg_immoffw:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i8 src_bimm = vcpu.fetch8();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write8(dest_mem + offset, src_bimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::bimm_in_dreg_regoff:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i8 src_bimm = vcpu.fetch8();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write8(dest_mem + offset, src_bimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::bimm_in_dreg_immoffb:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i8 src_bimm = vcpu.fetch8();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write8(dest_mem + offset, src_bimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_in_dreg_immoffw:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_mem = vcpu.readRegister(vcpu.fetch8());
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write16(dest_mem + offset, mem.read16(src_mem));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_in_dreg_regoff:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_mem = vcpu.readRegister(vcpu.fetch8());
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write16(dest_mem + offset, mem.read16(src_mem));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_in_dreg_immoffb:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_mem = vcpu.readRegister(vcpu.fetch8());
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write16(dest_mem + offset, mem.read16(src_mem));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_in_dreg_immoffw:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_mem = vcpu.readRegister(vcpu.fetch8());
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write8(dest_mem + offset, mem.read8(src_mem));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_in_dreg_regoff:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_mem = vcpu.readRegister(vcpu.fetch8());
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write8(dest_mem + offset, mem.read8(src_mem));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_in_dreg_immoffb:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
i16 src_mem = vcpu.readRegister(vcpu.fetch8());
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
mem.write8(dest_mem + offset, mem.read8(src_mem));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wimm_in_mem_immoffw:
|
||||
{
|
||||
u16 dest_mem = vcpu.fetch16();
|
||||
i16 src_wimm = vcpu.fetch16();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
mem.write16(dest_mem + offset, src_wimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::wimm_in_mem_regoff:
|
||||
{
|
||||
u16 dest_mem = vcpu.fetch16();
|
||||
i16 src_wimm = vcpu.fetch16();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
mem.write16(dest_mem + offset, src_wimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::wimm_in_mem_immoffb:
|
||||
{
|
||||
u16 dest_mem = vcpu.fetch16();
|
||||
i16 src_wimm = vcpu.fetch16();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
mem.write16(dest_mem + offset, src_wimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::bimm_in_mem_immoffw:
|
||||
{
|
||||
u16 dest_mem = vcpu.fetch16();
|
||||
i8 src_bimm = vcpu.fetch8();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
mem.write8(dest_mem + offset, src_bimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::bimm_in_mem_regoff:
|
||||
{
|
||||
u16 dest_mem = vcpu.fetch16();
|
||||
i8 src_bimm = vcpu.fetch8();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
mem.write8(dest_mem + offset, src_bimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::bimm_in_mem_immoffb:
|
||||
{
|
||||
u16 dest_mem = vcpu.fetch16();
|
||||
i8 src_bimm = vcpu.fetch8();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
mem.write8(dest_mem + offset, src_bimm);
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_immoffw_in_dreg:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
mem.write16(dest_mem, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_regoff_in_dreg:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
mem.write16(dest_mem, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_immoffb_in_dreg:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
mem.write16(dest_mem, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_immoffw_in_dreg:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
mem.write8(dest_mem, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_regoff_in_dreg:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
mem.write8(dest_mem, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_immoffb_in_dreg:
|
||||
{
|
||||
u8 dest_dreg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
u16 dest_mem = vcpu.readRegister(dest_dreg);
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
mem.write8(dest_mem, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wmem_immoffw_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_mem = vcpu.fetch16();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
vcpu.writeRegister16(dest_reg, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wmem_regoff_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_mem = vcpu.fetch16();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
vcpu.writeRegister16(dest_reg, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wmem_immoffb_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_mem = vcpu.fetch16();
|
||||
u8 offset = vcpu.fetch8();
|
||||
vcpu.writeRegister16(dest_reg, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bmem_immoffw_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_mem = vcpu.fetch16();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
vcpu.writeRegister8(dest_reg, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bmem_regoff_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_mem = vcpu.fetch16();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
vcpu.writeRegister8(dest_reg, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bmem_immoffb_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_mem = vcpu.fetch16();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
vcpu.writeRegister8(dest_reg, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_immoffw_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
vcpu.writeRegister16(dest_reg, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_regoff_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
vcpu.writeRegister16(dest_reg, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::wdreg_immoffb_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
vcpu.writeRegister16(dest_reg, mem.read16(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_immoffw_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u16 offset = vcpu.fetch16();
|
||||
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
vcpu.writeRegister8(dest_reg, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_regoff_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u16 offset = vcpu.readRegister(vcpu.fetch8());
|
||||
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
vcpu.writeRegister8(dest_reg, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
case OpCodes::bdreg_immoffb_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_dreg = vcpu.fetch8();
|
||||
u8 offset = vcpu.fetch8();
|
||||
|
||||
u16 src_mem = vcpu.readRegister(src_dreg);
|
||||
vcpu.writeRegister8(dest_reg, mem.read8(src_mem + offset));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
//TODO: Error
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
String ExtAlu::getOpCodeString(u8 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";
|
||||
}
|
||||
}
|
||||
|
||||
u8 ExtAlu::getInstructionSIze(u8 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;
|
||||
u8 inst = vcpu.fetch8();
|
||||
switch (inst)
|
||||
{
|
||||
case OpCodes::addipu_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
u16 dest_val = vcpu.readRegister(dest_reg);
|
||||
u16 src_val = vcpu.readRegister(src_reg);
|
||||
u16 res = dest_val + src_val;
|
||||
vcpu.writeRegister16(dest_reg, (i16)res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::addipu_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
u16 dest_val = vcpu.readRegister(dest_reg);
|
||||
u16 res = dest_val + src_val;
|
||||
vcpu.writeRegister16(dest_reg, (i16)res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::subipu_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
u16 dest_val = vcpu.readRegister(dest_reg);
|
||||
u16 src_val = vcpu.readRegister(src_reg);
|
||||
u16 res = dest_val - src_val;
|
||||
vcpu.writeRegister16(dest_reg, (i16)res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::subipu_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
u16 dest_val = vcpu.readRegister(dest_reg);
|
||||
u16 res = dest_val - src_val;
|
||||
vcpu.writeRegister16(dest_reg, (i16)res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::mulipu_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
u16 dest_val = vcpu.readRegister(dest_reg);
|
||||
u16 src_val = vcpu.readRegister(src_reg);
|
||||
u16 res = dest_val * src_val;
|
||||
vcpu.writeRegister16(dest_reg, (i16)res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::mulipu_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
u16 dest_val = vcpu.readRegister(dest_reg);
|
||||
u16 res = dest_val * src_val;
|
||||
vcpu.writeRegister16(dest_reg, (i16)res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::divipu_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
u16 dest_val = vcpu.readRegister(dest_reg);
|
||||
u16 src_val = vcpu.readRegister(src_reg);
|
||||
u16 res = dest_val / src_val;
|
||||
u16 rv = dest_val % src_val;
|
||||
vcpu.writeRegister16(dest_reg, (i16)res);
|
||||
vcpu.writeRegister16(data::Registers::RV, (i16)rv);
|
||||
}
|
||||
break;
|
||||
case OpCodes::divipu_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
u16 dest_val = vcpu.readRegister(dest_reg);
|
||||
u16 res = dest_val / src_val;
|
||||
u16 rv = dest_val % src_val;
|
||||
vcpu.writeRegister16(dest_reg, (i16)res);
|
||||
vcpu.writeRegister16(data::Registers::RV, (i16)rv);
|
||||
}
|
||||
break;
|
||||
case OpCodes::addip_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
i16 src_val = vcpu.readRegister(src_reg);
|
||||
i16 res = dest_val + src_val;
|
||||
vcpu.writeRegister16(dest_reg, res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::addip_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
i16 res = dest_val + src_val;
|
||||
vcpu.writeRegister16(dest_reg, res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::subip_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
i16 src_val = vcpu.readRegister(src_reg);
|
||||
i16 res = dest_val - src_val;
|
||||
vcpu.writeRegister16(dest_reg, res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::subip_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
i16 res = dest_val - src_val;
|
||||
vcpu.writeRegister16(dest_reg, res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::mulip_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
i16 src_val = vcpu.readRegister(src_reg);
|
||||
i16 res = dest_val * src_val;
|
||||
vcpu.writeRegister16(dest_reg, res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::mulip_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
i16 res = dest_val * src_val;
|
||||
vcpu.writeRegister16(dest_reg, res);
|
||||
}
|
||||
break;
|
||||
case OpCodes::divip_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
i16 src_val = vcpu.readRegister(src_reg);
|
||||
i16 res = dest_val / src_val;
|
||||
i16 rv = dest_val % src_val;
|
||||
vcpu.writeRegister16(dest_reg, res);
|
||||
vcpu.writeRegister16(data::Registers::RV, rv);
|
||||
}
|
||||
break;
|
||||
case OpCodes::divip_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
i16 res = dest_val / src_val;
|
||||
i16 rv = dest_val % src_val;
|
||||
vcpu.writeRegister16(dest_reg, res);
|
||||
vcpu.writeRegister16(data::Registers::RV, rv);
|
||||
}
|
||||
break;
|
||||
case OpCodes::andip_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
i16 src_val = vcpu.readRegister(src_reg);
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
vcpu.writeRegister16(dest_reg, src_val & dest_val);
|
||||
}
|
||||
break;
|
||||
case OpCodes::andip_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
i16 value = vcpu.readRegister(dest_reg);
|
||||
vcpu.writeRegister16(dest_reg, value & src_val);
|
||||
}
|
||||
break;
|
||||
case OpCodes::orip_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
i16 src_val = vcpu.readRegister(src_reg);
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
vcpu.writeRegister16(dest_reg, src_val | dest_val);
|
||||
}
|
||||
break;
|
||||
case OpCodes::orip_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
i16 value = vcpu.readRegister(dest_reg);
|
||||
vcpu.writeRegister16(dest_reg, value | src_val);
|
||||
}
|
||||
break;
|
||||
case OpCodes::xorip_reg_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u8 src_reg = vcpu.fetch8();
|
||||
i16 src_val = vcpu.readRegister(src_reg);
|
||||
i16 dest_val = vcpu.readRegister(dest_reg);
|
||||
vcpu.writeRegister16(dest_reg, src_val ^ dest_val);
|
||||
}
|
||||
break;
|
||||
case OpCodes::xorip_imm_in_reg:
|
||||
{
|
||||
u8 dest_reg = vcpu.fetch8();
|
||||
u16 src_val = vcpu.fetch16();
|
||||
i16 value = vcpu.readRegister(dest_reg);
|
||||
vcpu.writeRegister16(dest_reg, value ^ src_val);
|
||||
}
|
||||
break;
|
||||
case OpCodes::notip_reg:
|
||||
{
|
||||
u8 regAddr = vcpu.fetch8();
|
||||
i16 value = vcpu.readRegister(regAddr);
|
||||
vcpu.writeRegister16(regAddr, ~value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
//TODO: Error
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
105
src/hardware/CPUExtensions.hpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#pragma once
|
||||
|
||||
#include "../tools/GlobalData.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
namespace cpuext
|
||||
{
|
||||
class ExtMov : public data::CPUExtension
|
||||
{
|
||||
public: class OpCodes
|
||||
{
|
||||
public:
|
||||
inline static constexpr u8 wimm_in_dreg_immoffw = 0x10;
|
||||
inline static constexpr u8 wimm_in_dreg_regoff = 0x11;
|
||||
inline static constexpr u8 wimm_in_dreg_immoffb = 0x12;
|
||||
inline static constexpr u8 bimm_in_dreg_immoffw = 0x13;
|
||||
inline static constexpr u8 bimm_in_dreg_regoff = 0x14;
|
||||
inline static constexpr u8 bimm_in_dreg_immoffb = 0x15;
|
||||
inline static constexpr u8 wdreg_in_dreg_immoffw = 0x16;
|
||||
inline static constexpr u8 wdreg_in_dreg_regoff = 0x17;
|
||||
inline static constexpr u8 wdreg_in_dreg_immoffb = 0x18;
|
||||
inline static constexpr u8 bdreg_in_dreg_immoffw = 0x19;
|
||||
inline static constexpr u8 bdreg_in_dreg_regoff = 0x1A;
|
||||
inline static constexpr u8 bdreg_in_dreg_immoffb = 0x1B;
|
||||
|
||||
inline static constexpr u8 wimm_in_mem_immoffw = 0x30;
|
||||
inline static constexpr u8 wimm_in_mem_regoff = 0x31;
|
||||
inline static constexpr u8 wimm_in_mem_immoffb = 0x32;
|
||||
inline static constexpr u8 bimm_in_mem_immoffw = 0x33;
|
||||
inline static constexpr u8 bimm_in_mem_regoff = 0x34;
|
||||
inline static constexpr u8 bimm_in_mem_immoffb = 0x35;
|
||||
|
||||
inline static constexpr u8 wdreg_immoffw_in_dreg = 0x40;
|
||||
inline static constexpr u8 wdreg_regoff_in_dreg = 0x41;
|
||||
inline static constexpr u8 wdreg_immoffb_in_dreg = 0x42;
|
||||
inline static constexpr u8 bdreg_immoffw_in_dreg = 0x43;
|
||||
inline static constexpr u8 bdreg_regoff_in_dreg = 0x44;
|
||||
inline static constexpr u8 bdreg_immoffb_in_dreg = 0x45;
|
||||
|
||||
inline static constexpr u8 wmem_immoffw_in_reg = 0x50;
|
||||
inline static constexpr u8 wmem_regoff_in_reg = 0x51;
|
||||
inline static constexpr u8 wmem_immoffb_in_reg = 0x52;
|
||||
inline static constexpr u8 bmem_immoffw_in_reg = 0x53;
|
||||
inline static constexpr u8 bmem_regoff_in_reg = 0x54;
|
||||
inline static constexpr u8 bmem_immoffb_in_reg = 0x55;
|
||||
inline static constexpr u8 wdreg_immoffw_in_reg = 0x56;
|
||||
inline static constexpr u8 wdreg_regoff_in_reg = 0x57;
|
||||
inline static constexpr u8 wdreg_immoffb_in_reg = 0x58;
|
||||
inline static constexpr u8 bdreg_immoffw_in_reg = 0x59;
|
||||
inline static constexpr u8 bdreg_regoff_in_reg = 0x5A;
|
||||
inline static constexpr u8 bdreg_immoffb_in_reg = 0x5B;
|
||||
};
|
||||
public:
|
||||
inline ExtMov(void) : data::CPUExtension(data::OpCodes::Ext01, "extmov") { }
|
||||
String getOpCodeString(u8 opCode) override;
|
||||
u8 getInstructionSIze(u8 opCode) override;
|
||||
bool execute(VirtualCPU& vcpu) override;
|
||||
};
|
||||
|
||||
class ExtAlu : public data::CPUExtension
|
||||
{
|
||||
public: class OpCodes
|
||||
{
|
||||
public:
|
||||
inline static constexpr u8 addipu_reg_in_reg = 0x10;
|
||||
inline static constexpr u8 addipu_imm_in_reg = 0x11;
|
||||
inline static constexpr u8 subipu_reg_in_reg = 0x12;
|
||||
inline static constexpr u8 subipu_imm_in_reg = 0x13;
|
||||
inline static constexpr u8 mulipu_reg_in_reg = 0x14;
|
||||
inline static constexpr u8 mulipu_imm_in_reg = 0x15;
|
||||
inline static constexpr u8 divipu_reg_in_reg = 0x16;
|
||||
inline static constexpr u8 divipu_imm_in_reg = 0x17;
|
||||
|
||||
inline static constexpr u8 addip_reg_in_reg = 0x20;
|
||||
inline static constexpr u8 addip_imm_in_reg = 0x21;
|
||||
inline static constexpr u8 subip_reg_in_reg = 0x22;
|
||||
inline static constexpr u8 subip_imm_in_reg = 0x23;
|
||||
inline static constexpr u8 mulip_reg_in_reg = 0x24;
|
||||
inline static constexpr u8 mulip_imm_in_reg = 0x25;
|
||||
inline static constexpr u8 divip_reg_in_reg = 0x26;
|
||||
inline static constexpr u8 divip_imm_in_reg = 0x27;
|
||||
|
||||
inline static constexpr u8 andip_reg_in_reg = 0x30;
|
||||
inline static constexpr u8 andip_imm_in_reg = 0x31;
|
||||
inline static constexpr u8 orip_reg_in_reg = 0x32;
|
||||
inline static constexpr u8 orip_imm_in_reg = 0x33;
|
||||
inline static constexpr u8 xorip_reg_in_reg = 0x34;
|
||||
inline static constexpr u8 xorip_imm_in_reg = 0x35;
|
||||
inline static constexpr u8 notip_reg = 0x36;
|
||||
|
||||
};
|
||||
public:
|
||||
inline ExtAlu(void) : data::CPUExtension(data::OpCodes::Ext02, "extalu") { }
|
||||
String getOpCodeString(u8 opCode) override;
|
||||
u8 getInstructionSIze(u8 opCode) override;
|
||||
bool execute(VirtualCPU& vcpu) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostd/Types.hpp>
|
||||
#include <ostd/data/BaseObject.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
class IMemoryDevice
|
||||
class IMemoryDevice : public ostd::BaseObject
|
||||
{
|
||||
public:
|
||||
virtual int8_t read8(uint16_t addr) = 0;
|
||||
virtual int16_t read16(uint16_t addr) = 0;
|
||||
virtual int8_t write8(uint16_t addr, int8_t value) = 0;
|
||||
virtual int16_t write16(uint16_t addr, int16_t value) = 0;
|
||||
virtual i8 read8(u16 addr) = 0;
|
||||
virtual i16 read16(u16 addr) = 0;
|
||||
virtual i8 write8(u16 addr, i8 value) = 0;
|
||||
virtual i16 write16(u16 addr, i16 value) = 0;
|
||||
virtual inline ostd::ByteStream* getByteStream(void) = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "MemoryMapper.hpp"
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <iostream>
|
||||
#include <ostd/data/Types.hpp>
|
||||
|
||||
#include "../tools/GlobalData.hpp"
|
||||
|
||||
|
|
@ -12,44 +11,44 @@ namespace dragon
|
|||
{
|
||||
}
|
||||
|
||||
int8_t MemoryMapper::read8(uint16_t addr)
|
||||
i8 MemoryMapper::read8(u16 addr)
|
||||
{
|
||||
auto region = findRegion(addr);
|
||||
if (region == nullptr) return 0x0000; //TODO: Error
|
||||
uint16_t finalAddr = (region->remap ? addr - region->startAddress : addr);
|
||||
u16 finalAddr = (region->remap ? addr - region->startAddress : addr);
|
||||
return region->device->read8(finalAddr);
|
||||
}
|
||||
|
||||
int16_t MemoryMapper::read16(uint16_t addr)
|
||||
i16 MemoryMapper::read16(u16 addr)
|
||||
{
|
||||
auto region = findRegion(addr);
|
||||
if (region == nullptr) return 0x0000; //TODO: Error
|
||||
uint16_t finalAddr = (region->remap ? addr - region->startAddress : addr);
|
||||
u16 finalAddr = (region->remap ? addr - region->startAddress : addr);
|
||||
return region->device->read16(finalAddr);
|
||||
}
|
||||
|
||||
int8_t MemoryMapper::write8(uint16_t addr, int8_t value)
|
||||
i8 MemoryMapper::write8(u16 addr, i8 value)
|
||||
{
|
||||
auto region = findRegion(addr);
|
||||
if (region == nullptr) return 0x0000; //TODO: Error
|
||||
uint16_t finalAddr = (region->remap ? addr - region->startAddress : addr);
|
||||
u16 finalAddr = (region->remap ? addr - region->startAddress : addr);
|
||||
return region->device->write8(finalAddr, value);
|
||||
}
|
||||
|
||||
int16_t MemoryMapper::write16(uint16_t addr, int16_t value)
|
||||
i16 MemoryMapper::write16(u16 addr, i16 value)
|
||||
{
|
||||
auto region = findRegion(addr);
|
||||
if (region == nullptr) return 0x0000; //TODO: Error
|
||||
uint16_t finalAddr = (region->remap ? addr - region->startAddress : addr);
|
||||
u16 finalAddr = (region->remap ? addr - region->startAddress : addr);
|
||||
return region->device->write16(finalAddr, value);
|
||||
}
|
||||
|
||||
void MemoryMapper::mapDevice(IMemoryDevice& device, uint16_t startAddr, uint16_t endAddr, bool remap, ostd::String name)
|
||||
void MemoryMapper::mapDevice(IMemoryDevice& device, u16 startAddr, u16 endAddr, bool remap, String name)
|
||||
{
|
||||
m_regions.push_back({ &device, startAddr, endAddr, remap, name });
|
||||
}
|
||||
|
||||
ostd::String MemoryMapper::getMemoryRegionName(uint16_t address)
|
||||
String MemoryMapper::getMemoryRegionName(u16 address)
|
||||
{
|
||||
tMemoryRegion* region = findRegion(address);
|
||||
if (region == nullptr) return "Invalid";
|
||||
|
|
@ -61,15 +60,15 @@ namespace dragon
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
MemoryMapper::tMemoryRegion* MemoryMapper::findRegion(uint16_t address)
|
||||
MemoryMapper::tMemoryRegion* MemoryMapper::findRegion(u16 address)
|
||||
{
|
||||
for (auto& region : m_regions)
|
||||
{
|
||||
if (address >= region.startAddress && address <= region.endAddress)
|
||||
return ®ion;
|
||||
}
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::MM_RegionNotFound, ostd::StringEditor("Memory device not found for address: ").add(ostd::Utils::getHexStr(address, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::MM_RegionNotFound, String("Memory device not found for address: ").add(String::getHexStr(address, true, 2)));
|
||||
return nullptr; //TODO: Error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "IMemoryDevice.hpp"
|
||||
#include <ostd/string/String.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace dragon
|
||||
|
|
@ -12,30 +13,30 @@ namespace dragon
|
|||
private: struct tMemoryRegion
|
||||
{
|
||||
IMemoryDevice* device { nullptr };
|
||||
uint16_t startAddress { 0x0000 };
|
||||
uint16_t endAddress { 0x0000 };
|
||||
u16 startAddress { 0x0000 };
|
||||
u16 endAddress { 0x0000 };
|
||||
bool remap { false };
|
||||
ostd::String name { "" };
|
||||
String name { "" };
|
||||
};
|
||||
|
||||
public:
|
||||
MemoryMapper(void);
|
||||
int8_t read8(uint16_t addr) override;
|
||||
int16_t read16(uint16_t addr) override;
|
||||
int8_t write8(uint16_t addr, int8_t value) override;
|
||||
int16_t write16(uint16_t addr, int16_t value) override;
|
||||
i8 read8(u16 addr) override;
|
||||
i16 read16(u16 addr) override;
|
||||
i8 write8(u16 addr, i8 value) override;
|
||||
i16 write16(u16 addr, i16 value) override;
|
||||
|
||||
void mapDevice(IMemoryDevice& device, uint16_t startAddr, uint16_t endAddr, bool remap = false, ostd::String name = "");
|
||||
void mapDevice(IMemoryDevice& device, u16 startAddr, u16 endAddr, bool remap = false, String name = "");
|
||||
|
||||
ostd::String getMemoryRegionName(uint16_t address);
|
||||
String getMemoryRegionName(u16 address);
|
||||
|
||||
ostd::ByteStream* getByteStream(void) override;
|
||||
|
||||
private:
|
||||
tMemoryRegion* findRegion(uint16_t address);
|
||||
tMemoryRegion* findRegion(u16 address);
|
||||
|
||||
private:
|
||||
std::vector<tMemoryRegion> m_regions;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostd/Types.hpp>
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <ostd/Bitfields.hpp>
|
||||
#include <ostd/data/Types.hpp>
|
||||
#include <ostd/data/Bitfields.hpp>
|
||||
#include <ostd/utils/Time.hpp>
|
||||
#include "IMemoryDevice.hpp"
|
||||
|
||||
#include "../tools/GlobalData.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
class DragonRuntime;
|
||||
|
|
@ -12,43 +14,69 @@ namespace dragon
|
|||
{
|
||||
class VirtualCPU
|
||||
{
|
||||
public: enum class eDebugProfilerTimeUnits { Millis = 0, Secs = 1, Micros = 2, Nanos = 3 };
|
||||
public:
|
||||
VirtualCPU(IMemoryDevice& memory);
|
||||
int16_t readRegister(uint8_t reg);
|
||||
int16_t writeRegister(uint8_t reg, int16_t value);
|
||||
i16 readRegister(u8 reg);
|
||||
i16 writeRegister16(u8 reg, i16 value);
|
||||
i8 writeRegister8(u8 reg, i8 value);
|
||||
//TODO: Implement readRegister8 and readRegister16 functions
|
||||
|
||||
int8_t fetch8(void);
|
||||
int16_t fetch16(void);
|
||||
i8 fetch8(void);
|
||||
i16 fetch16(void);
|
||||
|
||||
void pushToStack(int16_t value);
|
||||
int16_t popFromStack(void);
|
||||
void pushToStack(i16 value);
|
||||
i16 popFromStack(void);
|
||||
|
||||
void pushStackFrame(void);
|
||||
void popStackFrame(void);
|
||||
|
||||
bool readFlag(uint8_t flg);
|
||||
void setFlag(uint8_t flg, bool val = true);
|
||||
bool readFlag(u8 flg);
|
||||
void setFlag(u8 flg, bool val = true);
|
||||
|
||||
void handleInterrupt(uint8_t intValue);
|
||||
void handleInterrupt(u8 intValue, bool hardware);
|
||||
|
||||
bool loadExtension(void);
|
||||
bool execute(void);
|
||||
|
||||
inline bool isHalted(void) const { return m_halt; }
|
||||
inline uint8_t getCurrentInstruction(void) const { return m_currentInst; }
|
||||
inline u8 getCurrentInstruction(void) const { return m_currentInst; }
|
||||
inline bool isInDebugBreakPoint(void) const { return m_isDebugBreakPoint; }
|
||||
inline bool isRamDumped(void) const { return m_ramDumped; }
|
||||
inline bool isInBIOSMOde(void) const { return m_biosMode; }
|
||||
inline bool isInSubRoutine(void) const { return m_subroutineCounter > 0; }
|
||||
inline i32 getSubRoutineCounter(void) const { return m_subroutineCounter; }
|
||||
inline data::CPUExtension* getCurrentCPUExtension(void) const { return m_currentExtension; }
|
||||
inline u8 getCurrentCPUExtensionInstruction(void) const { return m_currentExtInst; }
|
||||
inline bool isOffsetAddressingModeEnabled(void) const { return m_isOffsetAddressingEnabled; }
|
||||
inline u16 getCurrentOffset(void) const { return m_currentOffset; }
|
||||
|
||||
private:
|
||||
int16_t m_registers[20];
|
||||
i16 m_registers[20];
|
||||
ostd::BitField_16 m_tempFlags;
|
||||
IMemoryDevice& m_memory;
|
||||
uint16_t m_stackFrameSize { 0 };
|
||||
u16 m_stackFrameSize { 0 };
|
||||
bool m_halt { false };
|
||||
uint8_t m_currentInst { 0x00 };
|
||||
u8 m_currentInst { 0x00 };
|
||||
u8 m_currentAddr { 0x00 };
|
||||
bool m_biosMode { true };
|
||||
bool m_isInInterruptHandler { false };
|
||||
i32 m_interruptHandlerCount { 0 };
|
||||
bool m_isDebugBreakPoint { false };
|
||||
bool m_ramDumped { false };
|
||||
bool m_debugModeEnabled { false };
|
||||
i32 m_subroutineCounter { 0 };
|
||||
bool m_debugProfilerStarted { false };
|
||||
|
||||
bool m_isOffsetAddressingEnabled { false };
|
||||
u16 m_currentOffset { 0x0000 };
|
||||
|
||||
data::CPUExtension* m_extensions[16];
|
||||
data::CPUExtension* m_currentExtension { nullptr };
|
||||
u8 m_currentExtInst { 0x00 };
|
||||
|
||||
ostd::Counter m_profilerTimer;
|
||||
|
||||
friend class dragon::DragonRuntime;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
319
src/hardware/VirtualDisplay.cpp
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
#include "VirtualDisplay.hpp"
|
||||
#include <ogfx/render/PixelRenderer.hpp>
|
||||
#include "../runtime/DragonRuntime.hpp"
|
||||
#include "../tools/GlobalData.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
void VirtualDisplay::onInitialize(void)
|
||||
{
|
||||
m_renderer.initialize(*this);
|
||||
ogfx::PixelRenderer::TextRenderer::initialize();
|
||||
|
||||
text16_load_palettes();
|
||||
m_currentPaletteID = DragonRuntime::machine_config.text16_palette;
|
||||
if (m_currentPaletteID >= m_text16_palettes.size())
|
||||
m_text16_Currentpalette = m_text16_palettes[0];
|
||||
else
|
||||
m_text16_Currentpalette = m_text16_palettes[m_currentPaletteID];
|
||||
|
||||
text16_init_buffer();
|
||||
}
|
||||
|
||||
void VirtualDisplay::onDestroy(void) { }
|
||||
|
||||
void VirtualDisplay::onRender(void)
|
||||
{
|
||||
if (!isVisible()) return;
|
||||
auto& config = DragonRuntime::machine_config;
|
||||
auto& mem = DragonRuntime::memMap;
|
||||
u16 vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
|
||||
u8 video_mode = mem.read8(vga_addr + tRegisters::VideoMode);
|
||||
if (video_mode == tVideoModeValues::TextSingleColor)
|
||||
{
|
||||
u8 invert_colors = mem.read8(vga_addr + tRegisters::TextSingleInvertColors);
|
||||
if (m_refreshScreen)
|
||||
{
|
||||
if (invert_colors == 0)
|
||||
m_renderer.clear(config.singleColor_background);
|
||||
else
|
||||
m_renderer.clear(config.singleColor_foreground);
|
||||
for (i32 i = 0; i < m_singleTextLines.size(); i++)
|
||||
{
|
||||
auto& line = m_singleTextLines[i];
|
||||
if (invert_colors == 0)
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_foreground, config.singleColor_background);
|
||||
else
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_background, config.singleColor_foreground);
|
||||
}
|
||||
m_refreshScreen = false;
|
||||
}
|
||||
}
|
||||
else if (video_mode == tVideoModeValues::Text16Colors)
|
||||
{
|
||||
if (m_refreshScreen)
|
||||
{
|
||||
u8 clear_color = mem.read8(vga_addr + tRegisters::ClearColor);
|
||||
ostd::Color clearColor = m_text16_Currentpalette->getColor(clear_color);
|
||||
m_renderer.clear(clearColor);
|
||||
for (i32 i = 0; i < ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H; i++)
|
||||
{
|
||||
auto& cell = m_text16_buffer[i];
|
||||
ostd::Color background = m_text16_Currentpalette->getColor(cell.backgroundColor);
|
||||
ostd::Color foreground = m_text16_Currentpalette->getColor(cell.foregroundColor);
|
||||
char character = static_cast<char>(cell.character);
|
||||
auto xy = CONVERT_1D_2D(i, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H);
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(String().addChar(character), xy.x, xy.y, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, foreground, background);
|
||||
}
|
||||
m_refreshScreen = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_redrawScreen = m_redrawScreen && !DragonRuntime::vGraphicsInterface.readFlag(hw::interface::Graphics::tFlags::ScreenRedrawDisabled);
|
||||
if (m_redrawScreen)
|
||||
{
|
||||
__redraw_screen();
|
||||
}
|
||||
m_renderer.displayBuffer();
|
||||
}
|
||||
|
||||
// static char c = 'A';
|
||||
|
||||
void VirtualDisplay::onUpdate(void)
|
||||
{
|
||||
auto& mem = DragonRuntime::memMap;
|
||||
u16 vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
|
||||
u8 video_mode = mem.read8(vga_addr + tRegisters::VideoMode);
|
||||
u8 signal = mem.read8(vga_addr + tRegisters::Signal);
|
||||
if (signal == tSignalValues::Continue) return;
|
||||
if (video_mode == tVideoModeValues::TextSingleColor)
|
||||
{
|
||||
if (signal == tSignalValues::TextSingleColor_DirectPrintChar)
|
||||
{
|
||||
char c = (char)mem.read8(vga_addr + tRegisters::TextSingleCharacter);
|
||||
single_text_add_char_to_line(c);
|
||||
}
|
||||
else if (signal == tSignalValues::TextSingleColor_DirectPrintString)
|
||||
{
|
||||
u16 first_char_addr = mem.read16(vga_addr + tRegisters::TextSingleString);
|
||||
char c = ' ';
|
||||
int h = 0;
|
||||
while (c != 0)
|
||||
{
|
||||
char c = (char)mem.read8(first_char_addr);
|
||||
single_text_add_char_to_line(c);
|
||||
first_char_addr++;
|
||||
if (c == 0) break;
|
||||
}
|
||||
}
|
||||
else if (signal == tSignalValues::TextSingleColor_StoreChar)
|
||||
{
|
||||
char c = (char)mem.read8(vga_addr + tRegisters::TextSingleCharacter);
|
||||
single_text_add_char_to_buffer(c);
|
||||
}
|
||||
else if (signal == tSignalValues::TextSingleColor_DirectPrintBuffNoFlush)
|
||||
{
|
||||
single_text_print_buffer_no_flush();
|
||||
}
|
||||
else if (signal == tSignalValues::TextSingleColor_DirectPrintBuffAndFlush)
|
||||
{
|
||||
single_text_print_buffer_and_flush();
|
||||
}
|
||||
else if (signal == tSignalValues::TextSingleColor_FlushBuffer)
|
||||
{
|
||||
single_text_flush_buffer();
|
||||
}
|
||||
else if (signal == tSignalValues::ClearSCreen)
|
||||
{
|
||||
single_text_clear_screen();
|
||||
}
|
||||
else if (signal == tSignalValues::RefreshScreen)
|
||||
{
|
||||
single_text_refresh_screen();
|
||||
}
|
||||
}
|
||||
else if (video_mode == tVideoModeValues::Text16Colors)
|
||||
{
|
||||
if (signal == tSignalValues::Text16Color_WriteMemory)
|
||||
{
|
||||
hw::interface::Graphics::tText16_Cell textCell;
|
||||
|
||||
textCell.foregroundColor = mem.read8(vga_addr + tRegisters::MemControllerFGCol);
|
||||
textCell.backgroundColor = mem.read8(vga_addr + tRegisters::MemControllerBGCol);
|
||||
textCell.character = mem.read8(vga_addr + tRegisters::MemControllerChar);
|
||||
i16 x = mem.read16(vga_addr + tRegisters::MemControllerX);
|
||||
i16 y = mem.read16(vga_addr + tRegisters::MemControllerY);
|
||||
|
||||
//TODO: Remove this override used for testing purposes
|
||||
// for (i32 i = 0; i < ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H; i++)
|
||||
// {
|
||||
// auto xy = CONVERT_1D_2D(i, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H);
|
||||
// DragonRuntime::vGraphicsInterface.writeVRAM_16Colors(static_cast<u8>(xy.x), static_cast<u8>(xy.y), c++, 0, 15);
|
||||
// if (c > 'Z')
|
||||
// c = 'A';
|
||||
// }
|
||||
|
||||
DragonRuntime::vGraphicsInterface.writeVRAM_16Colors(static_cast<u8>(x), static_cast<u8>(y), textCell.character, textCell.backgroundColor, textCell.foregroundColor);
|
||||
}
|
||||
else if (signal == tSignalValues::ClearSCreen)
|
||||
{
|
||||
hw::interface::Graphics::tText16_Cell textCell;
|
||||
|
||||
textCell.foregroundColor = mem.read8(vga_addr + tRegisters::MemControllerFGCol);
|
||||
textCell.backgroundColor = mem.read8(vga_addr + tRegisters::MemControllerBGCol);
|
||||
textCell.character = mem.read8(vga_addr + tRegisters::MemControllerChar);
|
||||
|
||||
DragonRuntime::vGraphicsInterface.clearVRAM_16Colors(textCell.character, textCell.backgroundColor, textCell.foregroundColor);
|
||||
|
||||
m_redrawScreen = true;
|
||||
m_refreshScreen = true;
|
||||
}
|
||||
else if (signal == tSignalValues::RedrawScreen)
|
||||
{
|
||||
__redraw_screen();
|
||||
}
|
||||
else if (signal == tSignalValues::Text16Color_SwapBuffers)
|
||||
{
|
||||
DragonRuntime::vGraphicsInterface.swapBuffers_16Colors();
|
||||
__redraw_screen();
|
||||
}
|
||||
else if (signal == tSignalValues::Text16Color_Scroll)
|
||||
{
|
||||
DragonRuntime::vGraphicsInterface.scroll_16Colors();
|
||||
__redraw_screen();
|
||||
}
|
||||
}
|
||||
else return;
|
||||
mem.write8(vga_addr + tRegisters::Signal, tSignalValues::Continue);
|
||||
}
|
||||
|
||||
void VirtualDisplay::onFixedUpdate(f64 frameTime_s)
|
||||
{
|
||||
auto& config = DragonRuntime::machine_config;
|
||||
auto& mem = DragonRuntime::memMap;
|
||||
u16 vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
|
||||
u8 video_mode = mem.read8(vga_addr + tRegisters::VideoMode);
|
||||
u8 signal = mem.read8(vga_addr + tRegisters::Signal);
|
||||
if (video_mode == tVideoModeValues::Text16Colors)
|
||||
{
|
||||
m_refreshScreen = true;
|
||||
dragon::hw::interface::Graphics::tText16_Cell outTextCell;
|
||||
for (i32 i = 0; i < ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H; i++)
|
||||
{
|
||||
auto xy = CONVERT_1D_2D(i, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H);
|
||||
DragonRuntime::vGraphicsInterface.readVRAM_16Colors(xy.x, xy.y, outTextCell);
|
||||
m_text16_buffer[i] = outTextCell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualDisplay::__redraw_screen(void)
|
||||
{
|
||||
m_renderer.updateBuffer();
|
||||
DragonRuntime::cpu.handleInterrupt(data::InterruptCodes::Text16ModeScreenRefreshed, true);
|
||||
m_redrawScreen = false;
|
||||
m_refreshScreen = true;
|
||||
}
|
||||
|
||||
void VirtualDisplay::single_text_add_char_to_line(char c)
|
||||
{
|
||||
auto& config = DragonRuntime::machine_config;
|
||||
auto& mem = DragonRuntime::memMap;
|
||||
u16 vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
|
||||
u8 invert_colors = mem.read8(vga_addr + tRegisters::TextSingleInvertColors);
|
||||
if (m_singleTextLines.size() == 0)
|
||||
{
|
||||
m_singleTextLines.push_back(String().addChar(c));
|
||||
if (invert_colors == 0)
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_foreground, config.singleColor_background);
|
||||
else
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_background, config.singleColor_foreground);
|
||||
return;
|
||||
}
|
||||
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
|
||||
if (c == '\n')
|
||||
m_singleTextLines.push_back("");
|
||||
else if (isprint(c))
|
||||
{
|
||||
if (line.len() == ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H)
|
||||
{
|
||||
m_singleTextLines.push_back(String().addChar(c));
|
||||
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
|
||||
if (invert_colors == 0)
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_foreground, config.singleColor_background);
|
||||
else
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_background, config.singleColor_foreground);
|
||||
}
|
||||
else
|
||||
{
|
||||
line.addChar(c);
|
||||
if (invert_colors == 0)
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_foreground, config.singleColor_background);
|
||||
else
|
||||
ogfx::PixelRenderer::TextRenderer::drawString(String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_background, config.singleColor_foreground);
|
||||
}
|
||||
}
|
||||
else return;
|
||||
if (m_singleTextLines.size() == ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V + 1)
|
||||
{
|
||||
m_refreshScreen = true;
|
||||
m_singleTextLines.erase(m_singleTextLines.begin());
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualDisplay::single_text_add_char_to_buffer(char c)
|
||||
{
|
||||
if (c == '\n' || m_singleTextBuffer.len() == ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H)
|
||||
{
|
||||
single_text_print_buffer_and_flush();
|
||||
single_text_add_char_to_line(c);
|
||||
}
|
||||
else
|
||||
m_singleTextBuffer.addChar(c);
|
||||
}
|
||||
|
||||
void VirtualDisplay::single_text_flush_buffer(void)
|
||||
{
|
||||
m_singleTextBuffer = "";
|
||||
}
|
||||
|
||||
void VirtualDisplay::single_text_print_buffer_and_flush(void)
|
||||
{
|
||||
for (auto& ch : m_singleTextBuffer)
|
||||
single_text_add_char_to_line(ch);
|
||||
single_text_flush_buffer();
|
||||
}
|
||||
|
||||
void VirtualDisplay::single_text_print_buffer_no_flush(void)
|
||||
{
|
||||
for (auto& ch : m_singleTextBuffer)
|
||||
single_text_add_char_to_line(ch);
|
||||
}
|
||||
|
||||
void VirtualDisplay::single_text_clear_screen(void)
|
||||
{
|
||||
m_singleTextLines.clear();
|
||||
m_refreshScreen = true;
|
||||
}
|
||||
|
||||
void VirtualDisplay::single_text_refresh_screen(void)
|
||||
{
|
||||
m_refreshScreen = true;
|
||||
}
|
||||
|
||||
|
||||
void VirtualDisplay::text16_init_buffer(void)
|
||||
{
|
||||
for (i32 i = 0; i < ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H; i++)
|
||||
m_text16_buffer.push_back({ 0, 0, ' ' });
|
||||
}
|
||||
|
||||
void VirtualDisplay::text16_load_palettes(void)
|
||||
{
|
||||
m_text16_palettes.push_back(new data::BiosVideoDefaultPalette); //TODO: Delete, Memory Leak
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
97
src/hardware/VirtualDisplay.hpp
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
#pragma once
|
||||
|
||||
#include <ogfx/gui/Window.hpp>
|
||||
#include <ogfx/render/PixelRenderer.hpp>
|
||||
#include "../hardware/VirtualIODevices.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace data { class IBiosVideoPalette; }
|
||||
namespace hw
|
||||
{
|
||||
class VirtualDisplay : public ogfx::GraphicsWindow
|
||||
{
|
||||
public: struct tRegisters
|
||||
{
|
||||
inline static constexpr u8 VideoMode = 0x00;
|
||||
inline static constexpr u8 ClearColor = 0x01;
|
||||
inline static constexpr u8 Palette = 0x02;
|
||||
inline static constexpr u8 Signal = 0x03;
|
||||
inline static constexpr u8 TextSingleCharacter = 0x04;
|
||||
inline static constexpr u8 TextSingleInvertColors = 0x05;
|
||||
inline static constexpr u8 TextSingleString = 0x06;
|
||||
|
||||
inline static constexpr u8 Flags = 0x7E;
|
||||
|
||||
inline static constexpr u8 MemControllerX = 0x80;
|
||||
inline static constexpr u8 MemControllerY = 0x82;
|
||||
inline static constexpr u8 MemControllerChar = 0x84;
|
||||
inline static constexpr u8 MemControllerBGCol = 0x85;
|
||||
inline static constexpr u8 MemControllerFGCol = 0x86;
|
||||
};
|
||||
public: struct tVideoModeValues
|
||||
{
|
||||
inline static constexpr u8 TextSingleColor = 0x00;
|
||||
inline static constexpr u8 Text16Colors = 0x01;
|
||||
};
|
||||
public: struct tSignalValues
|
||||
{
|
||||
inline static constexpr u8 Continue = 0x00;
|
||||
|
||||
inline static constexpr u8 TextSingleColor_DirectPrintChar = 0x02;
|
||||
inline static constexpr u8 TextSingleColor_StoreChar = 0x03;
|
||||
inline static constexpr u8 TextSingleColor_DirectPrintBuffAndFlush = 0x04;
|
||||
inline static constexpr u8 TextSingleColor_FlushBuffer = 0x05;
|
||||
inline static constexpr u8 TextSingleColor_DirectPrintBuffNoFlush = 0x06;
|
||||
inline static constexpr u8 TextSingleColor_DirectPrintString = 0x07;
|
||||
|
||||
inline static constexpr u8 Text16Color_SwapBuffers = 0x10;
|
||||
inline static constexpr u8 Text16Color_WriteMemory = 0x11;
|
||||
inline static constexpr u8 Text16Color_Scroll = 0x12;
|
||||
|
||||
inline static constexpr u8 RefreshScreen = 0xE0;
|
||||
inline static constexpr u8 ClearSCreen = 0xE1;
|
||||
inline static constexpr u8 RedrawScreen = 0xE2;
|
||||
};
|
||||
public:
|
||||
inline void setFont(const String& fontPath) { m_font.init(fontPath); }
|
||||
|
||||
void onInitialize(void) override;
|
||||
void onDestroy(void) override;
|
||||
void onRender(void) override;
|
||||
void onUpdate(void) override;
|
||||
void onFixedUpdate(f64 frameTime_s) override;
|
||||
|
||||
inline void redrawScreen(void) { m_redrawScreen = true; }
|
||||
|
||||
private:
|
||||
void __redraw_screen(void);
|
||||
|
||||
void single_text_add_char_to_line(char c);
|
||||
void single_text_add_char_to_buffer(char c);
|
||||
void single_text_flush_buffer(void);
|
||||
void single_text_print_buffer_and_flush(void);
|
||||
void single_text_print_buffer_no_flush(void);
|
||||
|
||||
void single_text_clear_screen(void);
|
||||
void single_text_refresh_screen(void);
|
||||
|
||||
void text16_init_buffer(void);
|
||||
void text16_load_palettes(void);
|
||||
|
||||
private:
|
||||
ogfx::PixelRenderer m_renderer;
|
||||
ogfx::PixelRenderer::Font m_font;
|
||||
|
||||
std::vector<String> m_singleTextLines;
|
||||
String m_singleTextBuffer { "" };
|
||||
|
||||
std::vector<hw::interface::Graphics::tText16_Cell> m_text16_buffer;
|
||||
std::vector<data::IBiosVideoPalette*> m_text16_palettes;
|
||||
data::IBiosVideoPalette* m_text16_Currentpalette { nullptr };
|
||||
u8 m_currentPaletteID { 0 };
|
||||
|
||||
bool m_redrawScreen { true };
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -7,23 +7,23 @@ namespace dragon
|
|||
{
|
||||
namespace hw
|
||||
{
|
||||
void VirtualHardDrive::init(const ostd::String& dataFilePath)
|
||||
void VirtualHardDrive::init(const String& dataFilePath)
|
||||
{
|
||||
m_dataFile.open(dataFilePath, std::ios::out | std::ios::in | std::ios::binary);
|
||||
m_dataFile.open(dataFilePath.cpp_str(), std::ios::out | std::ios::in | std::ios::binary);
|
||||
if(!m_dataFile)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_UnableToMount, ostd::StringEditor("Unable to mount virtual HardDrive: ").add(dataFilePath).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_UnableToMount, String("Unable to mount virtual HardDrive: ").add(dataFilePath));
|
||||
return;
|
||||
}
|
||||
m_fileSize = m_dataFile.tellg();
|
||||
m_dataFile.seekg( 0, std::ios::end );
|
||||
m_fileSize = (int64_t)m_dataFile.tellg() - m_fileSize;
|
||||
m_fileSize = (i64)m_dataFile.tellg() - m_fileSize;
|
||||
m_dataFile.seekg( 0, std::ios::beg );
|
||||
m_diskID = s_nextDiskID++;
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
bool VirtualHardDrive::read(uint32_t addr, uint16_t size, ostd::ByteStream& outData)
|
||||
bool VirtualHardDrive::read(u32 addr, u16 size, ostd::ByteStream& outData)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
|
|
@ -35,10 +35,10 @@ namespace dragon
|
|||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_ReadOverflow, "Read Overflow on HardDrive.");
|
||||
return false;
|
||||
}
|
||||
uint8_t cell = 0;
|
||||
u8 cell = 0;
|
||||
outData.clear();
|
||||
m_dataFile.seekg(addr);
|
||||
for (int32_t i = 0; i < size; i++)
|
||||
for (i32 i = 0; i < size; i++)
|
||||
{
|
||||
m_dataFile.read((char*)&cell, sizeof(cell));
|
||||
outData.push_back(cell);
|
||||
|
|
@ -46,7 +46,7 @@ namespace dragon
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VirtualHardDrive::write(uint32_t addr, int8_t value)
|
||||
bool VirtualHardDrive::write(u32 addr, i8 value)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
|
|
@ -63,7 +63,7 @@ namespace dragon
|
|||
return true;
|
||||
}
|
||||
|
||||
void VirtualHardDrive::bufferedWrite(int8_t value)
|
||||
void VirtualHardDrive::bufferedWrite(i8 value)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
|
|
@ -73,7 +73,7 @@ namespace dragon
|
|||
m_writeBuffer.push_back(value);
|
||||
}
|
||||
|
||||
bool VirtualHardDrive::writeBuffer(uint32_t addr)
|
||||
bool VirtualHardDrive::writeBuffer(u32 addr)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <ostd/Utils.hpp>
|
||||
#include <ostd/string/String.hpp>
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
|
|
@ -11,28 +11,28 @@ namespace dragon
|
|||
{
|
||||
public:
|
||||
inline VirtualHardDrive(void) { m_initialized = false; }
|
||||
inline VirtualHardDrive(const ostd::String& dataFilePath) { init(dataFilePath); }
|
||||
void init(const ostd::String& dataFilePath);
|
||||
inline VirtualHardDrive(const String& dataFilePath) { init(dataFilePath); }
|
||||
void init(const String& dataFilePath);
|
||||
|
||||
bool read(uint32_t addr, uint16_t size, ostd::ByteStream& outData);
|
||||
bool write(uint32_t addr, int8_t value);
|
||||
void bufferedWrite(int8_t value);
|
||||
bool writeBuffer(uint32_t addr);
|
||||
bool read(u32 addr, u16 size, ostd::ByteStream& outData);
|
||||
bool write(u32 addr, i8 value);
|
||||
void bufferedWrite(i8 value);
|
||||
bool writeBuffer(u32 addr);
|
||||
|
||||
void unmount(void);
|
||||
|
||||
|
||||
inline bool isInitialized(void) const { return m_initialized; }
|
||||
inline uint64_t getSize(void) const { return m_fileSize; };
|
||||
inline u64 getSize(void) const { return m_fileSize; };
|
||||
inline bool isSame(VirtualHardDrive& vhdd) { return m_diskID == vhdd.m_diskID; }
|
||||
|
||||
private:
|
||||
std::fstream m_dataFile;
|
||||
bool m_initialized { false };
|
||||
uint64_t m_fileSize { 0 };
|
||||
u64 m_fileSize { 0 };
|
||||
ostd::ByteStream m_writeBuffer;
|
||||
uint32_t m_diskID { 0 };
|
||||
u32 m_diskID { 0 };
|
||||
|
||||
inline static uint32_t s_nextDiskID = 0;
|
||||
inline static u32 s_nextDiskID = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,56 @@
|
|||
#include "VirtualIODevices.hpp"
|
||||
#include <ostd/Utils.hpp>
|
||||
|
||||
#include "VirtualHardDrive.hpp"
|
||||
#include "MemoryMapper.hpp"
|
||||
#include "VirtualCPU.hpp"
|
||||
#include "VirtualRAM.hpp"
|
||||
|
||||
#include "../runtime/DragonRuntime.hpp"
|
||||
#include <ogfx/render/PixelRenderer.hpp>
|
||||
#include <ostd/io/Memory.hpp>
|
||||
|
||||
//TODO: Fix all access functions (reads and writes) ensuring the address is not out of bounds.
|
||||
// Right now the check is done, but just to push an error if out of bounds; the address
|
||||
// gets still used even in that case, which is really dumb and will probably crash the
|
||||
// runtime most of the time.
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
void VirtualBIOS::init(const ostd::String& biosFilePath)
|
||||
void VirtualBIOS::init(const String& biosFilePath)
|
||||
{
|
||||
bool loaded = ostd::Utils::loadByteStreamFromFile(biosFilePath, m_bios);
|
||||
bool loaded = ostd::Memory::loadByteStreamFromFile(biosFilePath, m_bios);
|
||||
if (!loaded)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_FailedToLoad, "Failed to load BIOS data.");
|
||||
if (m_bios.size() != 1024)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidSize, ostd::StringEditor("Invalid BIOS size: ").add(ostd::Utils::getHexStr(m_bios.size(), true, 2)).str());
|
||||
if (m_bios.size() != 4096) //TODO: Hardcoded
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidSize, String("Invalid BIOS size: ").add(String::getHexStr(m_bios.size(), true, 2)));
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
int8_t VirtualBIOS::read8(uint16_t addr)
|
||||
i8 VirtualBIOS::read8(u16 addr)
|
||||
{
|
||||
if (addr >= m_bios.size())
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::StringEditor("Invalid Byte BIOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, String("Invalid Byte BIOS location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return m_bios[addr];
|
||||
}
|
||||
|
||||
int16_t VirtualBIOS::read16(uint16_t addr)
|
||||
i16 VirtualBIOS::read16(u16 addr)
|
||||
{
|
||||
if (addr >= m_bios.size() - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::StringEditor("Invalid Word BIOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, String("Invalid Word BIOS location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return ((m_bios[addr + 0] << 8) & 0xFF00U)
|
||||
| ( m_bios[addr + 1] & 0x00FFU);
|
||||
}
|
||||
|
||||
int8_t VirtualBIOS::write8(uint16_t addr, int8_t value)
|
||||
i8 VirtualBIOS::write8(u16 addr, i8 value)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_WriteAttempt, "Attempting to write to BIOS memory map.");
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_WriteAttempt, String("Attempting to write to BIOS memory map: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
int16_t VirtualBIOS::write16(uint16_t addr, int16_t value)
|
||||
i16 VirtualBIOS::write16(u16 addr, i16 value)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_WriteAttempt, "Attempting to write to BIOS memory map.");
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_WriteAttempt, String("Attempting to write to BIOS memory map: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
|
|
@ -55,41 +62,41 @@ namespace dragon
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
InterruptVector::InterruptVector(void)
|
||||
{
|
||||
uint32_t dataSize = data::MemoryMapAddresses::IntVector_End - data::MemoryMapAddresses::IntVector_Start;
|
||||
for (int32_t i = 0; i < dataSize; i++)
|
||||
u32 dataSize = data::MemoryMapAddresses::IntVector_End - data::MemoryMapAddresses::IntVector_Start + 1;
|
||||
for (i32 i = 0; i < dataSize; i++)
|
||||
m_data.push_back(0x00);
|
||||
}
|
||||
|
||||
int8_t InterruptVector::read8(uint16_t addr)
|
||||
i8 InterruptVector::read8(u16 addr)
|
||||
{
|
||||
if (addr >= m_data.size())
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Byte IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Byte IntVector location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return m_data[addr];
|
||||
}
|
||||
|
||||
int16_t InterruptVector::read16(uint16_t addr)
|
||||
i16 InterruptVector::read16(u16 addr)
|
||||
{
|
||||
if (addr >= m_data.size() - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Word IntVector location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return ((m_data[addr + 0] << 8) & 0xFF00U)
|
||||
| ( m_data[addr + 1] & 0x00FFU);
|
||||
}
|
||||
|
||||
int8_t InterruptVector::write8(uint16_t addr, int8_t value)
|
||||
i8 InterruptVector::write8(u16 addr, i8 value)
|
||||
{
|
||||
if (addr >= m_data.size())
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Word IntVector location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
m_data[addr] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
int16_t InterruptVector::write16(uint16_t addr, int16_t value)
|
||||
i16 InterruptVector::write16(u16 addr, i16 value)
|
||||
{
|
||||
if (addr >= m_data.size() - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Word IntVector location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
m_data[addr + 0] = (value >> 8) & 0xFF;
|
||||
m_data[addr + 1] = value & 0xFF;
|
||||
return value;
|
||||
|
|
@ -103,60 +110,272 @@ namespace dragon
|
|||
|
||||
|
||||
|
||||
|
||||
VirtualKeyboard::VirtualKeyboard(void)
|
||||
|
||||
void VirtualKeyboard::init(void)
|
||||
{
|
||||
u32 dataSize = data::MemoryMapAddresses::Keyboard_End - data::MemoryMapAddresses::Keyboard_Start + 1;
|
||||
for (i32 i = 0; i < dataSize; i++)
|
||||
m_data.push_back(0x00);
|
||||
enableSignals();
|
||||
validate();
|
||||
connectSignal(ostd::BuiltinSignals::KeyPressed);
|
||||
connectSignal(ostd::BuiltinSignals::KeyReleased);
|
||||
connectSignal(ostd::BuiltinSignals::TextEntered);
|
||||
}
|
||||
|
||||
int8_t VirtualKeyboard::read8(uint16_t addr)
|
||||
i8 VirtualKeyboard::read8(u16 addr)
|
||||
{
|
||||
return 0x00;
|
||||
if (addr >= m_data.size())
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Byte KeyboardController location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return m_data[addr];
|
||||
}
|
||||
|
||||
int16_t VirtualKeyboard::read16(uint16_t addr)
|
||||
i16 VirtualKeyboard::read16(u16 addr)
|
||||
{
|
||||
return 0x0000;
|
||||
if (addr >= m_data.size() - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Word KeyboardController location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return ((m_data[addr + 0] << 8) & 0xFF00U)
|
||||
| ( m_data[addr + 1] & 0x00FFU);
|
||||
}
|
||||
|
||||
int8_t VirtualKeyboard::write8(uint16_t addr, int8_t value)
|
||||
i8 VirtualKeyboard::write8(u16 addr, i8 value)
|
||||
{
|
||||
return 0x00;
|
||||
if (addr >= m_data.size())
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Word KeyboardController location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
if (!DragonRuntime::cpu.isInBIOSMOde())
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::AccessViolation_BiosModeRequired, String("Attempting to write byte to KeyboardController while not in BIOS mode. Address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0;
|
||||
}
|
||||
return __write8(addr, value);
|
||||
}
|
||||
|
||||
int16_t VirtualKeyboard::write16(uint16_t addr, int16_t value)
|
||||
i16 VirtualKeyboard::write16(u16 addr, i16 value)
|
||||
{
|
||||
return 0x0000;
|
||||
if (addr >= m_data.size() - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Word KeyboardController location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
if (!DragonRuntime::cpu.isInBIOSMOde())
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::AccessViolation_BiosModeRequired, String("Attempting to write word to KeyboardController while not in BIOS mode. Address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0;
|
||||
}
|
||||
return __write16(addr, value);
|
||||
}
|
||||
|
||||
ostd::ByteStream* VirtualKeyboard::getByteStream(void)
|
||||
{
|
||||
return nullptr;
|
||||
return &m_data;
|
||||
}
|
||||
|
||||
void VirtualKeyboard::handleSignal(ostd::Signal& signal)
|
||||
{
|
||||
auto& cpu = DragonRuntime::cpu;
|
||||
const auto& state = SDL_GetKeyboardState(nullptr);
|
||||
if (signal.ID == ostd::BuiltinSignals::KeyPressed || signal.ID == ostd::BuiltinSignals::KeyReleased)
|
||||
{
|
||||
ogfx::KeyEventData& ked = (ogfx::KeyEventData&)signal.userData;
|
||||
m_modifiersBitFiels = __construct_modifiers_bitfield();
|
||||
__write16(tRegisters::Modifiers, (i16)m_modifiersBitFiels.value);
|
||||
__write16(tRegisters::KeyCode, __sdl_key_code_convert(ked.keyCode));
|
||||
if (ked.eventType == ogfx::KeyEventData::eKeyEvent::Pressed)
|
||||
cpu.handleInterrupt(data::InterruptCodes::KeyPressed, true);
|
||||
else if (ked.eventType == ogfx::KeyEventData::eKeyEvent::Pressed)
|
||||
cpu.handleInterrupt(data::InterruptCodes::KeyReleased, true);
|
||||
}
|
||||
else if (signal.ID == ostd::BuiltinSignals::TextEntered)
|
||||
{
|
||||
ogfx::KeyEventData& ked = (ogfx::KeyEventData&)signal.userData;
|
||||
m_modifiersBitFiels = __construct_modifiers_bitfield();
|
||||
__write16(tRegisters::Modifiers, (i16)m_modifiersBitFiels.value);
|
||||
__write16(tRegisters::KeyCode, (i16)ked.text[0]);
|
||||
cpu.handleInterrupt(data::InterruptCodes::TextEntered, true);
|
||||
}
|
||||
}
|
||||
|
||||
ostd::BitField_16 VirtualKeyboard::__construct_modifiers_bitfield(void)
|
||||
{
|
||||
ostd::BitField_16 bitfield;
|
||||
auto mod_state = SDL_GetModState();
|
||||
ostd::Bits::val(bitfield, tModifierBits::LeftShift, (mod_state & SDL_KMOD_LSHIFT));
|
||||
ostd::Bits::val(bitfield, tModifierBits::LeftControl, (mod_state & SDL_KMOD_LCTRL));
|
||||
ostd::Bits::val(bitfield, tModifierBits::LeftAlt, (mod_state & SDL_KMOD_LALT));
|
||||
ostd::Bits::val(bitfield, tModifierBits::LeftSuper, (mod_state & SDL_KMOD_LGUI));
|
||||
ostd::Bits::val(bitfield, tModifierBits::RightShift, (mod_state & SDL_KMOD_RSHIFT));
|
||||
ostd::Bits::val(bitfield, tModifierBits::RightControl, (mod_state & SDL_KMOD_RCTRL));
|
||||
ostd::Bits::val(bitfield, tModifierBits::RightAlt, (mod_state & SDL_KMOD_RALT));
|
||||
ostd::Bits::val(bitfield, tModifierBits::RightSuper, (mod_state & SDL_KMOD_RGUI));
|
||||
ostd::Bits::val(bitfield, tModifierBits::CapsLock, (mod_state & SDL_KMOD_CAPS));
|
||||
ostd::Bits::val(bitfield, tModifierBits::NumLock, (mod_state & SDL_KMOD_NUM));
|
||||
ostd::Bits::val(bitfield, tModifierBits::ScrolLLock, (mod_state & SDL_KMOD_SCROLL));
|
||||
return bitfield;
|
||||
}
|
||||
|
||||
i8 VirtualKeyboard::__write8(u16 addr, i8 value)
|
||||
{
|
||||
m_data[addr] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
i16 VirtualKeyboard::__write16(u16 addr, i16 value)
|
||||
{
|
||||
m_data[addr + 0] = (value >> 8) & 0xFF;
|
||||
m_data[addr + 1] = value & 0xFF;
|
||||
return value;
|
||||
}
|
||||
|
||||
i16 VirtualKeyboard::__sdl_key_code_convert(i32 keyCode)
|
||||
{
|
||||
switch (keyCode)
|
||||
{
|
||||
case SDLK_LCTRL: return (i16)eKeys::LeftCTRL;
|
||||
case SDLK_LSHIFT: return (i16)eKeys::LeftShift;
|
||||
case SDLK_LALT: return (i16)eKeys::LeftALT;
|
||||
case SDLK_LGUI: return (i16)eKeys::LeftSuper;
|
||||
case SDLK_RCTRL: return (i16)eKeys::RightCTRL;
|
||||
case SDLK_RSHIFT: return (i16)eKeys::RightShift;
|
||||
case SDLK_RGUI: return (i16)eKeys::RightSuper;
|
||||
case SDLK_RALT: return (i16)eKeys::RightALT;
|
||||
case SDLK_KP_DIVIDE: return (i16)eKeys::KeyPadDivide;
|
||||
case SDLK_KP_MULTIPLY: return (i16)eKeys::KeyPadMultiply;
|
||||
case SDLK_KP_MINUS: return (i16)eKeys::KeyPadMinus;
|
||||
case SDLK_KP_PLUS: return (i16)eKeys::KeyPadPlus;
|
||||
case SDLK_KP_ENTER: return (i16)eKeys::KeyPadEnter;
|
||||
case SDLK_KP_1: return (i16)eKeys::KeyPad1;
|
||||
case SDLK_KP_2: return (i16)eKeys::KeyPad2;
|
||||
case SDLK_KP_3: return (i16)eKeys::KeyPad3;
|
||||
case SDLK_KP_4: return (i16)eKeys::KeyPad4;
|
||||
case SDLK_KP_5: return (i16)eKeys::KeyPad5;
|
||||
case SDLK_KP_6: return (i16)eKeys::KeyPad6;
|
||||
case SDLK_KP_7: return (i16)eKeys::KeyPad7;
|
||||
case SDLK_KP_8: return (i16)eKeys::KeyPad8;
|
||||
case SDLK_KP_9: return (i16)eKeys::KeyPad9;
|
||||
case SDLK_KP_0: return (i16)eKeys::KeyPad0;
|
||||
case SDLK_KP_PERIOD: return (i16)eKeys::KeyPadPeriod;
|
||||
case SDLK_PRINTSCREEN: return (i16)eKeys::PrintScreen;
|
||||
case SDLK_INSERT: return (i16)eKeys::Insert;
|
||||
case SDLK_HOME: return (i16)eKeys::Home;
|
||||
case SDLK_PAGEUP: return (i16)eKeys::PageUp;
|
||||
case SDLK_END: return (i16)eKeys::End;
|
||||
case SDLK_PAGEDOWN: return (i16)eKeys::PageDown;
|
||||
case SDLK_RIGHT: return (i16)eKeys::RightArrow;
|
||||
case SDLK_LEFT: return (i16)eKeys::LeftArrow;
|
||||
case SDLK_DOWN: return (i16)eKeys::DownArrow;
|
||||
case SDLK_UP: return (i16)eKeys::UpArrow;
|
||||
case SDLK_CAPSLOCK: return (i16)eKeys::CapsLock;
|
||||
case SDLK_NUMLOCKCLEAR: return (i16)eKeys::NumLock;
|
||||
case SDLK_SCROLLLOCK: return (i16)eKeys::ScrollLock;
|
||||
case SDLK_F1: return (i16)eKeys::F1;
|
||||
case SDLK_F2: return (i16)eKeys::F2;
|
||||
case SDLK_F3: return (i16)eKeys::F3;
|
||||
case SDLK_F4: return (i16)eKeys::F4;
|
||||
case SDLK_F5: return (i16)eKeys::F5;
|
||||
case SDLK_F6: return (i16)eKeys::F6;
|
||||
case SDLK_F7: return (i16)eKeys::F7;
|
||||
case SDLK_F8: return (i16)eKeys::F8;
|
||||
case SDLK_F9: return (i16)eKeys::F9;
|
||||
case SDLK_F10: return (i16)eKeys::F10;
|
||||
case SDLK_F11: return (i16)eKeys::F11;
|
||||
case SDLK_F12: return (i16)eKeys::F12;
|
||||
case SDLK_DELETE: return (i16)eKeys::Delete;
|
||||
case SDLK_RETURN: return (i16)eKeys::Return;
|
||||
case SDLK_ESCAPE: return (i16)eKeys::Escape;
|
||||
case SDLK_BACKSPACE: return (i16)eKeys::Backspace;
|
||||
case SDLK_TAB: return (i16)eKeys::Tab;
|
||||
case SDLK_SPACE: return (i16)eKeys::Spacebar;
|
||||
case SDLK_EXCLAIM: return (i16)eKeys::ExclamationMark;
|
||||
case SDLK_DBLAPOSTROPHE: return (i16)eKeys::DoubleQuote;
|
||||
case SDLK_HASH: return (i16)eKeys::Hash;
|
||||
case SDLK_PERCENT: return (i16)eKeys::Percent;
|
||||
case SDLK_DOLLAR: return (i16)eKeys::DollarSign;
|
||||
case SDLK_AMPERSAND: return (i16)eKeys::Ampersand;
|
||||
case SDLK_APOSTROPHE: return (i16)eKeys::SingleQuote;
|
||||
case SDLK_LEFTPAREN: return (i16)eKeys::LeftParenthesis;
|
||||
case SDLK_RIGHTPAREN: return (i16)eKeys::RightParenthesis;
|
||||
case SDLK_ASTERISK: return (i16)eKeys::Asterisk;
|
||||
case SDLK_PLUS: return (i16)eKeys::Plus;
|
||||
case SDLK_COMMA: return (i16)eKeys::Comma;
|
||||
case SDLK_MINUS: return (i16)eKeys::Minus;
|
||||
case SDLK_PERIOD: return (i16)eKeys::Period;
|
||||
case SDLK_SLASH: return (i16)eKeys::ForwardSlash;
|
||||
case SDLK_0: return (i16)eKeys::Num0;
|
||||
case SDLK_1: return (i16)eKeys::Num1;
|
||||
case SDLK_2: return (i16)eKeys::Num2;
|
||||
case SDLK_3: return (i16)eKeys::Num3;
|
||||
case SDLK_4: return (i16)eKeys::Num4;
|
||||
case SDLK_5: return (i16)eKeys::Num5;
|
||||
case SDLK_6: return (i16)eKeys::Num6;
|
||||
case SDLK_7: return (i16)eKeys::Num7;
|
||||
case SDLK_8: return (i16)eKeys::Num8;
|
||||
case SDLK_9: return (i16)eKeys::Num9;
|
||||
case SDLK_COLON: return (i16)eKeys::Colon;
|
||||
case SDLK_SEMICOLON: return (i16)eKeys::Semicolon;
|
||||
case SDLK_LESS: return (i16)eKeys::LessThan;
|
||||
case SDLK_EQUALS: return (i16)eKeys::Equals;
|
||||
case SDLK_GREATER: return (i16)eKeys::GreaterThan;
|
||||
case SDLK_QUESTION: return (i16)eKeys::QuestionMark;
|
||||
case SDLK_AT: return (i16)eKeys::AtSign;
|
||||
case SDLK_LEFTBRACKET: return (i16)eKeys::LeftBracket;
|
||||
case SDLK_BACKSLASH: return (i16)eKeys::BackSlash;
|
||||
case SDLK_RIGHTBRACKET: return (i16)eKeys::RightBracket;
|
||||
case SDLK_CARET: return (i16)eKeys::Caret;
|
||||
case SDLK_UNDERSCORE: return (i16)eKeys::Underscore;
|
||||
case SDLK_GRAVE: return (i16)eKeys::BackQuote;
|
||||
case SDLK_A: return (i16)eKeys::LowerCase_a;
|
||||
case SDLK_B: return (i16)eKeys::LowerCase_b;
|
||||
case SDLK_C: return (i16)eKeys::LowerCase_c;
|
||||
case SDLK_D: return (i16)eKeys::LowerCase_d;
|
||||
case SDLK_E: return (i16)eKeys::LowerCase_e;
|
||||
case SDLK_F: return (i16)eKeys::LowerCase_f;
|
||||
case SDLK_G: return (i16)eKeys::LowerCase_g;
|
||||
case SDLK_H: return (i16)eKeys::LowerCase_h;
|
||||
case SDLK_I: return (i16)eKeys::LowerCase_i;
|
||||
case SDLK_J: return (i16)eKeys::LowerCase_j;
|
||||
case SDLK_K: return (i16)eKeys::LowerCase_k;
|
||||
case SDLK_L: return (i16)eKeys::LowerCase_l;
|
||||
case SDLK_M: return (i16)eKeys::LowerCase_m;
|
||||
case SDLK_N: return (i16)eKeys::LowerCase_n;
|
||||
case SDLK_O: return (i16)eKeys::LowerCase_o;
|
||||
case SDLK_P: return (i16)eKeys::LowerCase_p;
|
||||
case SDLK_Q: return (i16)eKeys::LowerCase_q;
|
||||
case SDLK_R: return (i16)eKeys::LowerCase_r;
|
||||
case SDLK_S: return (i16)eKeys::LowerCase_s;
|
||||
case SDLK_T: return (i16)eKeys::LowerCase_t;
|
||||
case SDLK_U: return (i16)eKeys::LowerCase_u;
|
||||
case SDLK_V: return (i16)eKeys::LowerCase_v;
|
||||
case SDLK_W: return (i16)eKeys::LowerCase_w;
|
||||
case SDLK_X: return (i16)eKeys::LowerCase_x;
|
||||
case SDLK_Y: return (i16)eKeys::LowerCase_y;
|
||||
case SDLK_Z: return (i16)eKeys::LowerCase_z;
|
||||
default: return (i16)eKeys::UpperCase_A;
|
||||
}
|
||||
return (i16)eKeys::UpperCase_A;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
VirtualMouse::VirtualMouse(void)
|
||||
{
|
||||
}
|
||||
|
||||
int8_t VirtualMouse::read8(uint16_t addr)
|
||||
i8 VirtualMouse::read8(u16 addr)
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
int16_t VirtualMouse::read16(uint16_t addr)
|
||||
i16 VirtualMouse::read16(u16 addr)
|
||||
{
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
int8_t VirtualMouse::write8(uint16_t addr, int8_t value)
|
||||
i8 VirtualMouse::write8(u16 addr, i8 value)
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
int16_t VirtualMouse::write16(uint16_t addr, int16_t value)
|
||||
i16 VirtualMouse::write16(u16 addr, i16 value)
|
||||
{
|
||||
return 0x0000;
|
||||
}
|
||||
|
|
@ -169,40 +388,40 @@ namespace dragon
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
VirtualBootloader::VirtualBootloader(void)
|
||||
{
|
||||
for (int32_t i = 0; i < 512; i++)
|
||||
for (i32 i = 0; i < 512; i++)
|
||||
m_mbr.push_back(0);
|
||||
}
|
||||
|
||||
int8_t VirtualBootloader::read8(uint16_t addr)
|
||||
i8 VirtualBootloader::read8(u16 addr)
|
||||
{
|
||||
if (addr >= m_mbr.size())
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::StringEditor("Invalid Byte MBR location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, String("Invalid Byte MBR location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return m_mbr[addr];
|
||||
}
|
||||
|
||||
int16_t VirtualBootloader::read16(uint16_t addr)
|
||||
i16 VirtualBootloader::read16(u16 addr)
|
||||
{
|
||||
if (addr >= m_mbr.size() - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::StringEditor("Invalid Word MBR location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, String("Invalid Word MBR location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return ((m_mbr[addr + 0] << 8) & 0xFF00U)
|
||||
| ( m_mbr[addr + 1] & 0x00FFU);
|
||||
}
|
||||
|
||||
int8_t VirtualBootloader::write8(uint16_t addr, int8_t value)
|
||||
i8 VirtualBootloader::write8(u16 addr, i8 value)
|
||||
{
|
||||
if (addr >= m_mbr.size())
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Word IntVector location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
m_mbr[addr] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
int16_t VirtualBootloader::write16(uint16_t addr, int16_t value)
|
||||
i16 VirtualBootloader::write16(u16 addr, i16 value)
|
||||
{
|
||||
if (addr >= m_mbr.size() - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, String("Invalid Word IntVector location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
m_mbr[addr + 0] = (value >> 8) & 0xFF;
|
||||
m_mbr[addr + 1] = value & 0xFF;
|
||||
return value;
|
||||
|
|
@ -216,57 +435,6 @@ namespace dragon
|
|||
|
||||
|
||||
|
||||
|
||||
VirtualBIOSVideo::VirtualBIOSVideo(VirtualRAM& memory) : m_memory(memory)
|
||||
{
|
||||
intptr_t iMemPtr = reinterpret_cast<intptr_t>(memory.getByteStream()->data());
|
||||
iMemPtr += data::MemoryMapAddresses::BIOSVideo_Start;
|
||||
m_dataPtr = reinterpret_cast<ostd::Byte*>(iMemPtr);
|
||||
}
|
||||
|
||||
int8_t VirtualBIOSVideo::read8(uint16_t addr)
|
||||
{
|
||||
if (addr >= m_size)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOSVideo_InvalidAddress, ostd::StringEditor("Invalid read Byte BiosVideo location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
return m_dataPtr[addr];
|
||||
}
|
||||
|
||||
int16_t VirtualBIOSVideo::read16(uint16_t addr)
|
||||
{
|
||||
if (addr >= m_size - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOSVideo_InvalidAddress, ostd::StringEditor("Invalid read Word BiosVideo location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
return ((m_dataPtr[addr + 0] << 8) & 0xFF00U)
|
||||
| ( m_dataPtr[addr + 1] & 0x00FFU);
|
||||
}
|
||||
|
||||
int8_t VirtualBIOSVideo::write8(uint16_t addr, int8_t value)
|
||||
{
|
||||
if (addr >= m_size)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOSVideo_InvalidAddress, ostd::StringEditor("Invalid read Byte BiosVideo location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
m_dataPtr[addr] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
int16_t VirtualBIOSVideo::write16(uint16_t addr, int16_t value)
|
||||
{
|
||||
if (addr >= m_size - 1)
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::BIOSVideo_InvalidAddress, ostd::StringEditor("Invalid read Word BiosVideo location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
m_dataPtr[addr + 0] = (value >> 8) & 0xFF;
|
||||
m_dataPtr[addr + 1] = value & 0xFF;
|
||||
return value;
|
||||
}
|
||||
|
||||
ostd::ByteStream* VirtualBIOSVideo::getByteStream(void)
|
||||
{
|
||||
m_dataCopy.clear();
|
||||
m_dataCopy.insert(m_dataCopy.end(), &m_dataPtr[0], &m_dataPtr[m_size]);
|
||||
return &m_dataCopy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace interface
|
||||
{
|
||||
Disk::Disk(MemoryMapper& memory, VirtualCPU& cpu) : m_memory(memory), m_cpu(cpu)
|
||||
|
|
@ -274,9 +442,9 @@ namespace dragon
|
|||
m_data.w_Byte(tRegisters::Signal, tSignalValues::Ignore);
|
||||
}
|
||||
|
||||
int8_t Disk::read8(uint16_t addr)
|
||||
i8 Disk::read8(u16 addr)
|
||||
{
|
||||
int8_t value = 0;
|
||||
i8 value = 0;
|
||||
if (!m_data.r_Byte(addr, value))
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_ControllerReadFailed, "Failed to read byte from HardDrive Controller");
|
||||
|
|
@ -285,9 +453,9 @@ namespace dragon
|
|||
return value;
|
||||
}
|
||||
|
||||
int16_t Disk::read16(uint16_t addr)
|
||||
i16 Disk::read16(u16 addr)
|
||||
{
|
||||
int16_t value = 0;
|
||||
i16 value = 0;
|
||||
if (!m_data.r_Word(addr, value))
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_ControllerReadFailed, "Failed to read word from HardDrive Controller");
|
||||
|
|
@ -296,7 +464,7 @@ namespace dragon
|
|||
return value;
|
||||
}
|
||||
|
||||
int8_t Disk::write8(uint16_t addr, int8_t value)
|
||||
i8 Disk::write8(u16 addr, i8 value)
|
||||
{
|
||||
if (addr >= tRegisters::FirstReadOnly)
|
||||
{
|
||||
|
|
@ -311,7 +479,7 @@ namespace dragon
|
|||
return value;
|
||||
}
|
||||
|
||||
int16_t Disk::write16(uint16_t addr, int16_t value)
|
||||
i16 Disk::write16(u16 addr, i16 value)
|
||||
{
|
||||
if (addr >= tRegisters::FirstReadOnly)
|
||||
{
|
||||
|
|
@ -333,8 +501,8 @@ namespace dragon
|
|||
|
||||
void Disk::cycleStep(void)
|
||||
{
|
||||
uint8_t signal = tSignalValues::Ignore;
|
||||
m_data.r_Byte(tRegisters::Signal, (int8_t&)signal);
|
||||
u8 signal = tSignalValues::Ignore;
|
||||
m_data.r_Byte(tRegisters::Signal, (i8&)signal);
|
||||
if (m_busy)
|
||||
{
|
||||
if (signal == tSignalValues::Cancel)
|
||||
|
|
@ -350,21 +518,21 @@ namespace dragon
|
|||
m_busy = false;
|
||||
return;
|
||||
}
|
||||
uint8_t status = 0;
|
||||
m_data.r_Byte(tRegisters::Status, (int8_t&)status);
|
||||
u8 status = 0;
|
||||
m_data.r_Byte(tRegisters::Status, (i8&)status);
|
||||
if (status == tStatusValues::Free)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_InvalidConfiguration, "Invalid HardDrive configuration: <status> register set to <free> while busy.");
|
||||
m_busy = false;
|
||||
return;
|
||||
}
|
||||
uint8_t currentDisk = 0;
|
||||
uint16_t currentSector = 0, currentAddress = 0, restDataSize = 0, memoryAddress = 0;
|
||||
m_data.r_Byte(tRegisters::CurrentDisk, (int8_t&)currentDisk);
|
||||
m_data.r_Word(tRegisters::CurrentSector, (int16_t&)currentSector);
|
||||
m_data.r_Word(tRegisters::CurrentAddress, (int16_t&)currentAddress);
|
||||
m_data.r_Word(tRegisters::RestDataSize, (int16_t&)restDataSize);
|
||||
m_data.r_Word(tRegisters::SourceData, (int16_t&)memoryAddress);
|
||||
u8 currentDisk = 0;
|
||||
u16 currentSector = 0, currentAddress = 0, restDataSize = 0, memoryAddress = 0;
|
||||
m_data.r_Byte(tRegisters::CurrentDisk, (i8&)currentDisk);
|
||||
m_data.r_Word(tRegisters::CurrentSector, (i16&)currentSector);
|
||||
m_data.r_Word(tRegisters::CurrentAddress, (i16&)currentAddress);
|
||||
m_data.r_Word(tRegisters::RestDataSize, (i16&)restDataSize);
|
||||
m_data.r_Word(tRegisters::SourceData, (i16&)memoryAddress);
|
||||
if (m_connectedDisks.count((data::VDiskID)currentDisk) == 0)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_InvalidDiskSelected, "Invalid HardDrive configuration: selected Disk not found.");
|
||||
|
|
@ -372,7 +540,7 @@ namespace dragon
|
|||
return;
|
||||
}
|
||||
auto& disk = *m_connectedDisks[currentDisk];
|
||||
uint32_t hddAddress = 0;
|
||||
u32 hddAddress = 0;
|
||||
if (currentAddress == 0xFFFF)
|
||||
{
|
||||
if (currentSector == 0xFFFF)
|
||||
|
|
@ -398,7 +566,7 @@ namespace dragon
|
|||
}
|
||||
else if (status == tStatusValues::Writing)
|
||||
{
|
||||
int8_t dataRead = m_memory.read8(memoryAddress);
|
||||
i8 dataRead = m_memory.read8(memoryAddress);
|
||||
if (!disk.write(hddAddress, dataRead))
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_WriteFailed, "HardDrive Error: Failed to write data.");
|
||||
|
|
@ -419,7 +587,7 @@ namespace dragon
|
|||
m_data.w_Byte(tRegisters::Status, tStatusValues::Free);
|
||||
m_data.w_Byte(tRegisters::Signal, tSignalValues::Ignore);
|
||||
m_busy = false;
|
||||
m_cpu.handleInterrupt(data::InterruptCodes::DiskInterfaceFFinished);
|
||||
m_cpu.handleInterrupt(data::InterruptCodes::DiskInterfaceFFinished, true);
|
||||
return;
|
||||
}
|
||||
currentAddress++;
|
||||
|
|
@ -430,14 +598,14 @@ namespace dragon
|
|||
return;
|
||||
}
|
||||
if (signal != tSignalValues::Start) return;
|
||||
uint8_t mode = 0, disk = 0;
|
||||
uint16_t sector = 0, address = 0, size = 0, srcAddr = 0;
|
||||
m_data.r_Byte(tRegisters::ModeSelector, (int8_t&)mode);
|
||||
m_data.r_Byte(tRegisters::DiskSelector, (int8_t&)disk);
|
||||
m_data.r_Word(tRegisters::SectorSelector, (int16_t&)sector);
|
||||
m_data.r_Word(tRegisters::AddressSelector, (int16_t&)address);
|
||||
m_data.r_Word(tRegisters::DataSize, (int16_t&)size);
|
||||
m_data.r_Word(tRegisters::DataSourceAddress, (int16_t&)srcAddr);
|
||||
u8 mode = 0, disk = 0;
|
||||
u16 sector = 0, address = 0, size = 0, srcAddr = 0;
|
||||
m_data.r_Byte(tRegisters::ModeSelector, (i8&)mode);
|
||||
m_data.r_Byte(tRegisters::DiskSelector, (i8&)disk);
|
||||
m_data.r_Word(tRegisters::SectorSelector, (i16&)sector);
|
||||
m_data.r_Word(tRegisters::AddressSelector, (i16&)address);
|
||||
m_data.r_Word(tRegisters::DataSize, (i16&)size);
|
||||
m_data.r_Word(tRegisters::DataSourceAddress, (i16&)srcAddr);
|
||||
if (mode == tModeValues::Read)
|
||||
m_data.w_Byte(tRegisters::Status, tStatusValues::Reading);
|
||||
else if (mode == tModeValues::Write)
|
||||
|
|
@ -458,18 +626,20 @@ namespace dragon
|
|||
m_busy = true;
|
||||
}
|
||||
|
||||
data::VDiskID Disk::connectDisk(VirtualHardDrive& hdd)
|
||||
bool Disk::connectDisk(VirtualHardDrive& hdd, data::VDiskID disk_id)
|
||||
{
|
||||
for (auto& disk : m_connectedDisks)
|
||||
{
|
||||
if (disk.second->isSame(hdd))
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_DiskAlreadyConnected, "Attempt to connect already connected Disk to Controller");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_connectedDisks[Disk::s_nextDiskID] = &hdd;
|
||||
return Disk::s_nextDiskID++;
|
||||
m_connectedDisks[disk_id] = &hdd;
|
||||
return true;
|
||||
// m_connectedDisks[Disk::s_nextDiskID] = &hdd;
|
||||
// return Disk::s_nextDiskID++;
|
||||
}
|
||||
|
||||
bool Disk::disconnectDisk(data::VDiskID diskID)
|
||||
|
|
@ -489,31 +659,165 @@ namespace dragon
|
|||
|
||||
Graphics::Graphics(void)
|
||||
{
|
||||
m_videoMemory.init(0xFFFF);
|
||||
m_vramStart = data::MemoryMapAddresses::VideoCardInterface_End - data::MemoryMapAddresses::VideoCardInterface_Start + 1;
|
||||
m_16Color_frameSize = ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * m_16Color_cellSize;
|
||||
m_16Color_currentFrameAddr = m_vramStart;
|
||||
m_16Color_secondFrameAddr = m_vramStart + m_16Color_frameSize;
|
||||
}
|
||||
|
||||
int8_t Graphics::read8(uint16_t addr)
|
||||
i8 Graphics::read8(u16 addr)
|
||||
{
|
||||
return 0x00;
|
||||
i8 outVal = 0;
|
||||
if (!m_videoMemory.r_Byte(addr, outVal))
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::Graphics_MemoryReadFailed, "Failed to read byte from Graphics Memory");
|
||||
return 0;
|
||||
}
|
||||
return outVal;
|
||||
}
|
||||
|
||||
int16_t Graphics::read16(uint16_t addr)
|
||||
i16 Graphics::read16(u16 addr)
|
||||
{
|
||||
return 0x0000;
|
||||
i16 outVal = 0;
|
||||
if (!m_videoMemory.r_Word(addr, outVal))
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::Graphics_MemoryReadFailed, "Failed to read word from Graphics Memory");
|
||||
return 0;
|
||||
}
|
||||
return outVal;
|
||||
}
|
||||
|
||||
int8_t Graphics::write8(uint16_t addr, int8_t value)
|
||||
i8 Graphics::write8(u16 addr, i8 value)
|
||||
{
|
||||
return 0x00;
|
||||
if (!m_videoMemory.w_Byte(addr, value))
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::Graphics_MemoryWriteFailed, "Failed to write byte to Graphics Memory");
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int16_t Graphics::write16(uint16_t addr, int16_t value)
|
||||
i16 Graphics::write16(u16 addr, i16 value)
|
||||
{
|
||||
return 0x0000;
|
||||
if (!m_videoMemory.w_Word(addr, value))
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::Graphics_MemoryWriteFailed, "Failed to write word to Graphics Memory");
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool Graphics::readFlag(u8 flg)
|
||||
{
|
||||
if (flg >= 16) return false;
|
||||
i16 outValue = 0;
|
||||
if (!m_videoMemory.r_Word(VirtualDisplay::tRegisters::Flags, outValue))
|
||||
return false; //TODO: Error
|
||||
m_tempFlags.value = outValue;
|
||||
return ostd::Bits::get(m_tempFlags, flg);
|
||||
}
|
||||
|
||||
void Graphics::setFlag(u8 flg, bool val)
|
||||
{
|
||||
if (flg >= 16) return;
|
||||
i16 outValue = 0;
|
||||
if (!m_videoMemory.r_Word(VirtualDisplay::tRegisters::Flags, outValue))
|
||||
return; //TODO: Error
|
||||
m_tempFlags.value = outValue;
|
||||
ostd::Bits::val(m_tempFlags, flg, val);
|
||||
if (!m_videoMemory.w_Word(VirtualDisplay::tRegisters::Flags, m_tempFlags.value))
|
||||
return; //TODO: Error
|
||||
}
|
||||
|
||||
ostd::ByteStream* Graphics::getByteStream(void)
|
||||
{
|
||||
return nullptr;
|
||||
return &m_videoMemory.getData();
|
||||
}
|
||||
|
||||
bool Graphics::readVRAM_16Colors(u8 x, u8 y, Graphics::tText16_Cell& outTextCell)
|
||||
{
|
||||
u16 cellOffset = static_cast<u16>(CONVERT_2D_1D(x, y, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H)) * 4;
|
||||
cellOffset += m_16Color_currentFrameAddr;
|
||||
i8 outVal = 0;
|
||||
if (!m_videoMemory.r_Byte(cellOffset + tText16_CellStructure::character, outVal))
|
||||
return false; //TODO: Error
|
||||
outTextCell.character = outVal;
|
||||
if (!m_videoMemory.r_Byte(cellOffset + tText16_CellStructure::background, outVal))
|
||||
return false; //TODO: Error
|
||||
outTextCell.backgroundColor = outVal;
|
||||
if (!m_videoMemory.r_Byte(cellOffset + tText16_CellStructure::foreground, outVal))
|
||||
return false; //TODO: Error
|
||||
outTextCell.foregroundColor = outVal;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Graphics::writeVRAM_16Colors(u8 x, u8 y, u8 character, u8 background, u8 foreground)
|
||||
{
|
||||
u16 cellOffset = static_cast<u16>(CONVERT_2D_1D(x, y, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H)) * 4;
|
||||
if (!readFlag(tFlags::DoubleBufferingEnabled))
|
||||
cellOffset += m_16Color_currentFrameAddr;
|
||||
else
|
||||
cellOffset += m_16Color_secondFrameAddr;
|
||||
if (!m_videoMemory.w_Byte(cellOffset + tText16_CellStructure::character, character))
|
||||
return false; //TODO: Error
|
||||
if (!m_videoMemory.w_Byte(cellOffset + tText16_CellStructure::background, background))
|
||||
return false; //TODO: Error
|
||||
if (!m_videoMemory.w_Byte(cellOffset + tText16_CellStructure::foreground, foreground))
|
||||
return false; //TODO: Error
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Graphics::clearVRAM_16Colors(u8 character, u8 background, u8 foreground)
|
||||
{
|
||||
for (i32 i = m_16Color_currentFrameAddr; i < m_16Color_currentFrameAddr + m_16Color_frameSize; i += 4)
|
||||
{
|
||||
m_videoMemory.w_Byte(i + tText16_CellStructure::character, character);
|
||||
m_videoMemory.w_Byte(i + tText16_CellStructure::background, background);
|
||||
m_videoMemory.w_Byte(i + tText16_CellStructure::foreground, foreground);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Graphics::swapBuffers_16Colors(void)
|
||||
{
|
||||
if (!readFlag(tFlags::DoubleBufferingEnabled))
|
||||
return;
|
||||
for (i32 i = m_16Color_currentFrameAddr, j = 0; i < m_16Color_currentFrameAddr + m_16Color_frameSize; i += 4, j += 4)
|
||||
{
|
||||
i8 outByte = 0;
|
||||
m_videoMemory.r_Byte(m_16Color_secondFrameAddr + j, outByte);
|
||||
m_videoMemory.w_Byte(i + tText16_CellStructure::character, outByte);
|
||||
m_videoMemory.r_Byte(m_16Color_secondFrameAddr + j + 1, outByte);
|
||||
m_videoMemory.w_Byte(i + tText16_CellStructure::background, outByte);
|
||||
m_videoMemory.r_Byte(m_16Color_secondFrameAddr + j + 2, outByte);
|
||||
m_videoMemory.w_Byte(i + tText16_CellStructure::foreground, outByte);
|
||||
}
|
||||
u16 tmp = m_16Color_currentFrameAddr;
|
||||
m_16Color_currentFrameAddr = m_16Color_secondFrameAddr;
|
||||
m_16Color_secondFrameAddr = tmp;
|
||||
}
|
||||
|
||||
void Graphics::scroll_16Colors(void)
|
||||
{
|
||||
i32 line_len = (ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H * 4);
|
||||
for (i32 i = m_16Color_currentFrameAddr + line_len; i < m_16Color_currentFrameAddr + m_16Color_frameSize; i += 4)
|
||||
{
|
||||
i32 k = i;
|
||||
i8 outByte = 0;
|
||||
m_videoMemory.r_Byte(k, outByte);
|
||||
m_videoMemory.w_Byte(k - line_len, outByte);
|
||||
k++;
|
||||
m_videoMemory.r_Byte(k, outByte);
|
||||
m_videoMemory.w_Byte(k - line_len, outByte);
|
||||
k++;
|
||||
m_videoMemory.r_Byte(k, outByte);
|
||||
m_videoMemory.w_Byte(k - line_len, outByte);
|
||||
}
|
||||
for (i32 i = m_16Color_currentFrameAddr + m_16Color_frameSize - line_len; i < m_16Color_currentFrameAddr + m_16Color_frameSize; i += 4)
|
||||
{
|
||||
m_videoMemory.w_Byte(i, 0x20);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -524,22 +828,22 @@ namespace dragon
|
|||
{
|
||||
}
|
||||
|
||||
int8_t SerialPort::read8(uint16_t addr)
|
||||
i8 SerialPort::read8(u16 addr)
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
int16_t SerialPort::read16(uint16_t addr)
|
||||
i16 SerialPort::read16(u16 addr)
|
||||
{
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
int8_t SerialPort::write8(uint16_t addr, int8_t value)
|
||||
i8 SerialPort::write8(u16 addr, i8 value)
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
int16_t SerialPort::write16(uint16_t addr, int16_t value)
|
||||
i16 SerialPort::write16(u16 addr, i16 value)
|
||||
{
|
||||
return 0x0000;
|
||||
}
|
||||
|
|
@ -553,10 +857,10 @@ namespace dragon
|
|||
|
||||
|
||||
|
||||
void CMOS::init(const ostd::String& cmosFilePath)
|
||||
void CMOS::init(const String& cmosFilePath)
|
||||
{
|
||||
m_size = data::MemoryMapAddresses::CMOS_End - data::MemoryMapAddresses::CMOS_Start + 1;
|
||||
m_dataFile.open(cmosFilePath, std::ios::out | std::ios::in | std::ios::binary);
|
||||
m_dataFile.open(cmosFilePath.cpp_str(), std::ios::out | std::ios::in | std::ios::binary);
|
||||
if(!m_dataFile)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_UnableToMount, "Unable to mount virtual CMOS chip.");
|
||||
|
|
@ -564,17 +868,17 @@ namespace dragon
|
|||
}
|
||||
m_fileSize = m_dataFile.tellg();
|
||||
m_dataFile.seekg( 0, std::ios::end );
|
||||
m_fileSize = (int64_t)m_dataFile.tellg() - m_fileSize;
|
||||
m_fileSize = (i64)m_dataFile.tellg() - m_fileSize;
|
||||
m_dataFile.seekg( 0, std::ios::beg );
|
||||
if (m_fileSize != m_size)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidSize, ostd::StringEditor("Invalid virtual CMOS chhip size: ").addi(m_fileSize).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidSize, String("Invalid virtual CMOS chhip size: ").add(m_fileSize));
|
||||
return;
|
||||
}
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
int8_t CMOS::read8(uint16_t addr)
|
||||
i8 CMOS::read8(u16 addr)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
|
|
@ -583,16 +887,16 @@ namespace dragon
|
|||
}
|
||||
if (addr >= m_size)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::StringEditor("Invalid Byte CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, String("Invalid Byte CMOS location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return false;
|
||||
}
|
||||
int8_t value = 0;
|
||||
i8 value = 0;
|
||||
m_dataFile.seekg(addr);
|
||||
m_dataFile.read((char*)&value, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
int16_t CMOS::read16(uint16_t addr)
|
||||
i16 CMOS::read16(u16 addr)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
|
|
@ -601,16 +905,16 @@ namespace dragon
|
|||
}
|
||||
if (addr >= m_size - 1)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::StringEditor("Invalid Word CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, String("Invalid Word CMOS location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0;
|
||||
}
|
||||
int8_t b1 = read8(addr);
|
||||
int8_t b2 = read8(addr + 1);
|
||||
i8 b1 = read8(addr);
|
||||
i8 b2 = read8(addr + 1);
|
||||
return ((b1 << 8) & 0xFF00U)
|
||||
| (b2 & 0x00FFU);
|
||||
| (b2 & 0x00FFU);
|
||||
}
|
||||
|
||||
int8_t CMOS::write8(uint16_t addr, int8_t value)
|
||||
i8 CMOS::write8(u16 addr, i8 value)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
|
|
@ -619,7 +923,12 @@ namespace dragon
|
|||
}
|
||||
if (addr >= m_size)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::StringEditor("Invalid Byte CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, String("Invalid Byte CMOS location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0;
|
||||
}
|
||||
if (!DragonRuntime::cpu.isInBIOSMOde())
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::AccessViolation_BiosModeRequired, String("Attempting to write byte to CMOS while not in BIOS mode. Address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0;
|
||||
}
|
||||
m_dataFile.seekp(addr);
|
||||
|
|
@ -627,7 +936,7 @@ namespace dragon
|
|||
return value;
|
||||
}
|
||||
|
||||
int16_t CMOS::write16(uint16_t addr, int16_t value)
|
||||
i16 CMOS::write16(u16 addr, i16 value)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
|
|
@ -636,11 +945,16 @@ namespace dragon
|
|||
}
|
||||
if (addr >= m_size - 1)
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::StringEditor("Invalid Word CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str());
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, String("Invalid Word CMOS location at address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0;
|
||||
}
|
||||
int8_t b1 = (value >> 8) & 0xFF;
|
||||
int8_t b2 = (value & 0xFF);
|
||||
if (!DragonRuntime::cpu.isInBIOSMOde())
|
||||
{
|
||||
data::ErrorHandler::pushError(data::ErrorCodes::AccessViolation_BiosModeRequired, String("Attempting to write word to CMOS while not in BIOS mode. Address: ").add(String::getHexStr(addr, true, 2)));
|
||||
return 0;
|
||||
}
|
||||
i8 b1 = (value >> 8) & 0xFF;
|
||||
i8 b2 = (value & 0xFF);
|
||||
write8(addr, b1);
|
||||
write8(addr + 1, b2);
|
||||
return value;
|
||||
|
|
@ -652,4 +966,4 @@ namespace dragon
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||