[0.2.1577] - Added Virtual Display (Text-Single-Color mode only)
This commit is contained in:
parent
42f25f4e0b
commit
cdd8afb05d
39 changed files with 914 additions and 227 deletions
|
|
@ -31,12 +31,14 @@ list(APPEND RUNTIME_SOURCE_FILES
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/gui/Renderer.cpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/MemoryMapper.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/MemoryMapper.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualIODevices.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualIODevices.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp
|
||||||
)
|
)
|
||||||
|
|
@ -47,12 +49,14 @@ list(APPEND DEBUGGER_SOURCE_FILES
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/gui/Renderer.cpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/MemoryMapper.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/MemoryMapper.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualIODevices.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualIODevices.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/DragonRuntime.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/runtime/DragonRuntime.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp
|
||||||
|
|
|
||||||
2
build.nr
2
build.nr
|
|
@ -1 +1 @@
|
||||||
1576
|
1578
|
||||||
|
|
|
||||||
14
count_lines.sh
Normal file
14
count_lines.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
green='\033[0;32m'
|
||||||
|
red='\033[0;31m'
|
||||||
|
clear='\033[0m'
|
||||||
|
|
||||||
|
printf "Counting lines of code...\n"
|
||||||
|
|
||||||
|
(find ./src/ -type f \( -iname \*.hpp -o -iname \*.cpp \) | xargs -n1 cpp -fpreprocessed -P | awk '!/^[{[:space:]}]*$/' | wc -l) > _lines.tmp 2> /dev/null
|
||||||
|
typeset -i netto_lines=$(cat _lines.tmp)
|
||||||
|
rm _lines.tmp
|
||||||
|
total_lines=$(find ./src/ -type f \( -iname \*.hpp -o -iname \*.cpp \) | xargs wc -l | sort -n | tail -1 | tr -d -c 0-9)
|
||||||
|
printf "Total: ${red}${total_lines}\n${clear}"
|
||||||
|
printf "Netto: ${green}${netto_lines}${clear} (No braces, comments or empty lines.)\n"
|
||||||
|
|
@ -7,7 +7,7 @@ rm -r ./win-release
|
||||||
cd bin
|
cd bin
|
||||||
|
|
||||||
printf "${green}Compiling vBIOS...\n${clear}"
|
printf "${green}Compiling vBIOS...\n${clear}"
|
||||||
./dasm dss/bios.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose
|
./dasm dss/bios/bios.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose
|
||||||
|
|
||||||
printf "\n${green}Creating Virtual Disk...\n${clear}"
|
printf "\n${green}Creating Virtual Disk...\n${clear}"
|
||||||
rm dragon/disk1.dr
|
rm dragon/disk1.dr
|
||||||
|
|
@ -19,8 +19,10 @@ printf "\n${green}Compiling MBR Block...\n${clear}"
|
||||||
printf "\n${green}Loading MBR Block...\n${clear}"
|
printf "\n${green}Loading MBR Block...\n${clear}"
|
||||||
./dtools load-binary dragon/disk1.dr dragon/mbr.bin 0x00000000
|
./dtools load-binary dragon/disk1.dr dragon/mbr.bin 0x00000000
|
||||||
|
|
||||||
printf "${green}Compiling Test Program...\n"
|
printf "${green}Compiling Test Program 1...\n"
|
||||||
./dasm dss/test.dss -o test.bin --save-disassembly disassembly/test.dds --verbose
|
./dasm dss/test1.dss -o test1.bin --save-disassembly disassembly/test1.dds --verbose
|
||||||
|
printf "${green}Compiling Test Program 2...\n"
|
||||||
|
./dasm dss/test2.dss -o test2.bin --save-disassembly disassembly/test2.dds --verbose
|
||||||
|
|
||||||
printf "${green}Creating Windows Release...\n"
|
printf "${green}Creating Windows Release...\n"
|
||||||
cd ..
|
cd ..
|
||||||
|
|
@ -31,17 +33,23 @@ cp ./bin/ddb.exe ./win-release
|
||||||
cp ./bin/dtools.exe ./win-release
|
cp ./bin/dtools.exe ./win-release
|
||||||
cp ./bin/dvm.exe ./win-release
|
cp ./bin/dvm.exe ./win-release
|
||||||
cp ./bin/font.bmp ./win-release
|
cp ./bin/font.bmp ./win-release
|
||||||
# cp ./bin/test.bin ./win-release
|
|
||||||
|
|
||||||
cp -r ./bin/config ./win-release
|
cp -r ./bin/config ./win-release
|
||||||
cp -r ./bin/disassembly/bios.dds ./win-release/disassembly
|
cp -r ./bin/disassembly/bios.dds ./win-release/disassembly
|
||||||
cp -r ./bin/disassembly/mbr.dds ./win-release/disassembly
|
cp -r ./bin/disassembly/mbr.dds ./win-release/disassembly
|
||||||
|
cp -r ./bin/disassembly/test1.dds ./win-release/disassembly
|
||||||
|
cp -r ./bin/disassembly/test2.dds ./win-release/disassembly
|
||||||
cp -r ./bin/dragon ./win-release
|
cp -r ./bin/dragon ./win-release
|
||||||
|
|
||||||
|
rm ./bin/disassembly/test1.dds
|
||||||
|
rm ./bin/disassembly/test2.dds
|
||||||
|
|
||||||
mkdir ./win-release/dss
|
mkdir ./win-release/dss
|
||||||
cp ./bin/dss/bios.dss ./win-release/dss
|
mkdir ./win-release/dss/bios
|
||||||
|
cp ./bin/dss/bios/bios.dss ./win-release/dss/bios
|
||||||
cp ./bin/dss/mbr.dss ./win-release/dss
|
cp ./bin/dss/mbr.dss ./win-release/dss
|
||||||
cp ./bin/dss/test.dss ./win-release/dss
|
cp ./bin/dss/test1.dss ./win-release/dss
|
||||||
|
cp ./bin/dss/test2.dss ./win-release/dss
|
||||||
|
|
||||||
cp C:/msys64/ucrt64/bin/libgcc_s_seh-1.dll ./win-release
|
cp C:/msys64/ucrt64/bin/libgcc_s_seh-1.dll ./win-release
|
||||||
cp C:/msys64/ucrt64/bin/libstdc++-6.dll ./win-release
|
cp C:/msys64/ucrt64/bin/libstdc++-6.dll ./win-release
|
||||||
|
|
@ -49,4 +57,5 @@ cp C:/msys64/ucrt64/bin/libwinpthread-1.dll ./win-release
|
||||||
cp C:/msys64/ucrt64/bin/SDL2.dll ./win-release
|
cp C:/msys64/ucrt64/bin/SDL2.dll ./win-release
|
||||||
cp C:/msys64/ucrt64/bin/libostd.dll ./win-release
|
cp C:/msys64/ucrt64/bin/libostd.dll ./win-release
|
||||||
|
|
||||||
cp ./run-test.bat ./win-release
|
cp ./extra/scripts/run-test-1.bat ./win-release
|
||||||
|
cp ./extra/scripts/run-test-2.bat ./win-release
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
Disks = dragon/disk1.dr
|
Disks = dragon/disk1.dr
|
||||||
Bios = dragon/bios.bin
|
Bios = dragon/bios.bin
|
||||||
CMOS = dragon/cmos.dr
|
CMOS = dragon/cmos.dr
|
||||||
|
SingleColor_foreground = #009900FF
|
||||||
|
SingleColor_background = #111111FF
|
||||||
122
extra/dragon info/DragonVM Information Sheet
Normal file
122
extra/dragon info/DragonVM Information Sheet
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
#==========================================================================================================================================
|
||||||
|
# Memory Map
|
||||||
|
#==========================================================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
0x0000 BIOS (4096 Bytes)
|
||||||
|
0x0FFF
|
||||||
|
-------
|
||||||
|
0x1000 CMOS (128 Bytes)
|
||||||
|
BootDisk: 0x0010
|
||||||
|
0x107F
|
||||||
|
-------
|
||||||
|
0x1080 INTERRUPT VECTOR (512 Bytes)
|
||||||
|
Status: 1 Byte
|
||||||
|
0xFF: Enabled
|
||||||
|
0x00: Disabled
|
||||||
|
Handler Address: 2 Byte
|
||||||
|
...Repeat...
|
||||||
|
0x127F
|
||||||
|
-------
|
||||||
|
0x1280 KEYBOARD MAPPING (224 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
|
||||||
|
|
||||||
|
0xE0: Refresh Screen
|
||||||
|
0xE1: Clear Screen
|
||||||
|
0x04: Text Single Color Character
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
|
||||||
|
0xE0: Refresh Screen
|
||||||
|
0xE1: Clear Screen
|
||||||
|
|
||||||
|
|
||||||
|
Machine Specific - Hardware Interrupts:
|
||||||
|
=======================================
|
||||||
|
0x80: Disk Interface Finished
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
0x0000 BIOS (4096 Bytes)
|
|
||||||
0x0FFF
|
|
||||||
-------
|
|
||||||
0x1000 CMOS (128 Bytes)
|
|
||||||
BootDisk: 0x0010
|
|
||||||
0x107F
|
|
||||||
-------
|
|
||||||
0x1080 INTERRUPT VECTOR (512 Bytes)
|
|
||||||
Status: 1 Byte
|
|
||||||
0xFF: Enabled
|
|
||||||
0x00: Disabled
|
|
||||||
Handler Address: 2 Byte
|
|
||||||
...Repeat...
|
|
||||||
0x127F
|
|
||||||
-------
|
|
||||||
0x1280 KEYBOARD MAPPING (224 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: Single Color
|
|
||||||
0x01: 16-color
|
|
||||||
0x02: 256-color
|
|
||||||
0x03: True Color Mode
|
|
||||||
0x01: Clear Color (1 Byte)
|
|
||||||
0x02: Palette (1 Byte)
|
|
||||||
0x03: Signal (1 Byte)
|
|
||||||
0x00: Continue
|
|
||||||
0x01: Clear Screen
|
|
||||||
0x16FF
|
|
||||||
-------
|
|
||||||
0x1700 GENERIC SERIAL INTERFACE (64 Bytes)
|
|
||||||
0x173F
|
|
||||||
-------
|
|
||||||
0x1740 RAM (59583 Bytes)
|
|
||||||
0xFFFF
|
|
||||||
|
|
@ -1,13 +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
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 122 KiB |
Binary file not shown.
|
|
@ -5,21 +5,51 @@
|
||||||
DISK_INTERFACE 0x1580
|
DISK_INTERFACE 0x1580
|
||||||
RAM 0x1740
|
RAM 0x1740
|
||||||
CMOS 0x1000
|
CMOS 0x1000
|
||||||
|
VGA 0x1600
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@group CMOS_Settings
|
@group CMOS_Settings
|
||||||
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
|
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@group VGA_Registers
|
||||||
|
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
|
||||||
|
SIGNAL { MemoryAddresses.VGA + 0x0003 }
|
||||||
|
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
|
||||||
|
|
||||||
|
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
|
||||||
|
@end
|
||||||
|
|
||||||
|
@group VGA_VideoModes
|
||||||
|
TEXT_SINGLE_COLOR 0x00
|
||||||
|
@end
|
||||||
|
|
||||||
|
@group Sig_VGA_Text_Single_Color
|
||||||
|
CONTINUE 0x00
|
||||||
|
PRINT_CHAR 0x02
|
||||||
|
STORE_CHAR 0x03
|
||||||
|
PRINT_FLUSH_BUFF 0x04
|
||||||
|
FLUSH_BUFF 0x05
|
||||||
|
PRINT_BUFF 0x06
|
||||||
|
|
||||||
|
REFRESH_SCREEN 0xE0
|
||||||
|
CLEAR_SCREEN 0xE1
|
||||||
|
@end
|
||||||
|
|
||||||
|
@define S_REG_1 0x07
|
||||||
|
@define S_REG_2 0x08
|
||||||
|
@define S_REG_3 0x09
|
||||||
## ===============================================================================================
|
## ===============================================================================================
|
||||||
|
|
||||||
.load 0x0000 ## BIOS is mapped to address 0x0000 in memory
|
.load 0x0000 ## BIOS is mapped to address 0x0000 in memory
|
||||||
.data
|
.data
|
||||||
$bios_version_number 0x00, 0x01 ## BIOS Version stored in memory
|
$_bios_name "DragonBIOS"
|
||||||
|
$_bios_version_number_maj 0x00, 0x00
|
||||||
|
$_bios_version_number_min 0x00, 0x03
|
||||||
|
|
||||||
## ============================= BIOS Program =============================
|
## ============================= BIOS Program =============================
|
||||||
.code
|
.code
|
||||||
## mov FL, 0
|
movb [VGA_Registers.VIDEO_MODE], VGA_VideoModes.TEXT_SINGLE_COLOR ## Enable Text_Single_Color graphics mode
|
||||||
## jmp 0x1740
|
|
||||||
mov FL, 0b0000000000000001 ## Zero the FL Register and enable interrupts
|
mov FL, 0b0000000000000001 ## Zero the FL Register and enable interrupts
|
||||||
movb [{MemoryAddresses.INT_VEC + (0x20 * 3)}], 0xFF ## Setting up int 0x20 handler
|
movb [{MemoryAddresses.INT_VEC + (0x20 * 3)}], 0xFF ## Setting up int 0x20 handler
|
||||||
mov [{MemoryAddresses.INT_VEC + (0x20 * 3) + 1}], $_int_20_handler ## --
|
mov [{MemoryAddresses.INT_VEC + (0x20 * 3) + 1}], $_int_20_handler ## --
|
||||||
|
|
@ -29,12 +59,30 @@
|
||||||
mov R8, 0x30 ## -Passing the interrupt's code to setup
|
mov R8, 0x30 ## -Passing the interrupt's code to setup
|
||||||
int 0x20 ## -Calling int 0x20 with 0x00 as parameter, to set new handler up
|
int 0x20 ## -Calling int 0x20 with 0x00 as parameter, to set new handler up
|
||||||
|
|
||||||
## MBR Loading
|
mov R10, 0x03
|
||||||
|
mov R9, $_bios_name
|
||||||
|
int 0x30
|
||||||
|
mov R10, 0x01
|
||||||
|
mov R9, 32
|
||||||
|
int 0x30
|
||||||
|
mov R10, 0x04
|
||||||
|
mov R9, [$_bios_version_number_maj]
|
||||||
|
int 0x30
|
||||||
|
mov R10, 0x01
|
||||||
|
mov R9, 46
|
||||||
|
int 0x30
|
||||||
|
mov R10, 0x04
|
||||||
|
mov R9, [$_bios_version_number_min]
|
||||||
|
int 0x30
|
||||||
|
mov R10, 0x02
|
||||||
|
int 0x30
|
||||||
|
|
||||||
|
## MBR Loading //TODO: Figure out why and is not working
|
||||||
and FL, 0b1111111111111110 ## Disable interrupts
|
and FL, 0b1111111111111110 ## Disable interrupts
|
||||||
push 0
|
push 0
|
||||||
call $_load_mbr_data_block
|
call $_load_mbr_data_block
|
||||||
or FL, 0b0000000000000001 ## Enable interrupts
|
or FL, 0b0000000000000001 ## Enable interrupts
|
||||||
## ----
|
## ---- //TODO: Figure out why or is not working
|
||||||
|
|
||||||
jmp MemoryAddresses.MBR ## Jump to start of MBR in memory
|
jmp MemoryAddresses.MBR ## Jump to start of MBR in memory
|
||||||
hlt ## Just in case somehow execution reaches this point
|
hlt ## Just in case somehow execution reaches this point
|
||||||
|
|
@ -84,10 +132,78 @@ _int_20_end:
|
||||||
## ========================== BIOS Video Interrupt handler =========================
|
## ========================== BIOS Video Interrupt handler =========================
|
||||||
_int_30_handler:
|
_int_30_handler:
|
||||||
mov ACC, R10
|
mov ACC, R10
|
||||||
jeq $_int_30_clear_screen, 0x0000
|
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_clear_screen, 0x00E0
|
||||||
|
jeq $_int_30_refresh_screen, 0x00E1
|
||||||
jmp $_int_30_end
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
debug_break
|
||||||
|
jmp $_int_30_end
|
||||||
|
|
||||||
|
|
||||||
_int_30_clear_screen:
|
_int_30_clear_screen:
|
||||||
nop
|
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:
|
_int_30_end:
|
||||||
rti
|
rti
|
||||||
## ==================================================================================
|
## ==================================================================================
|
||||||
|
|
@ -132,4 +248,44 @@ _set_interrupt_vector_entry_end:
|
||||||
mov *R1, ACC
|
mov *R1, ACC
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
_print_integer:
|
||||||
|
mov R1, 0
|
||||||
|
arg ACC
|
||||||
|
jne $_print_integer_loop, 0
|
||||||
|
push 48 ## '0' ASCII is 48
|
||||||
|
inc R1
|
||||||
|
jmp $_print_integer_loop_end
|
||||||
|
_print_integer_loop:
|
||||||
|
jeq $_print_integer_loop_end, 0
|
||||||
|
div ACC, 10
|
||||||
|
mov R2, ACC
|
||||||
|
add RV, 48 ## '0' ASCII is 48
|
||||||
|
push ACC
|
||||||
|
inc R1
|
||||||
|
mov ACC, R2
|
||||||
|
jmp $_print_integer_loop
|
||||||
|
_print_integer_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_loop_end, 0
|
||||||
|
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
|
||||||
|
|
||||||
.fixed 4096, 0x00 ## BIOS Needs to be 4096 Bytes exactly
|
.fixed 4096, 0x00 ## BIOS Needs to be 4096 Bytes exactly
|
||||||
|
|
@ -1,80 +1,48 @@
|
||||||
.load 0x1740
|
##=================================================================================================================================
|
||||||
|
## This is the test2 program for the Dragon Virtual Machine. This example simply demonstrates the Virtual Display in Text-Single-Color
|
||||||
|
## mode, by printing an increasing counter followed by whatever is in the $string variable. The program also clears the screen
|
||||||
|
## every 10 lines.
|
||||||
|
##=================================================================================================================================
|
||||||
|
|
||||||
@struct Rectangle
|
.load 0x1740
|
||||||
width:2 > 0x11, 0x22
|
|
||||||
height:2 > 0x99
|
|
||||||
x:2
|
|
||||||
y:2 > 0xAA
|
|
||||||
@end
|
|
||||||
|
|
||||||
.data
|
.data
|
||||||
$string "Hello World!!"
|
$string "Hello World!!"
|
||||||
$rect <Rectangle> = (0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88)
|
|
||||||
$test_byte 0xAF
|
|
||||||
$super_long_variable_name 0x01, 0x02, 0x03, 0x04
|
|
||||||
|
|
||||||
.code
|
.code
|
||||||
begin:
|
mov R1, 99 ## Zero the counter
|
||||||
mov R10, Rectangle.SIZE
|
infinite_loop:
|
||||||
mov R9, [$rect.height]
|
inc R1 ## Increment the counter
|
||||||
mov R8, [$rect.width]
|
div R1, 10 ## Divide the counter by 10
|
||||||
mov R7, [$rect.x]
|
mov ACC, RV
|
||||||
mov R5, $strlen
|
jne $no_clear_screen, 0 ## If reminder not zero, keep going
|
||||||
push $string
|
mov R10, 0xE0 ## Else clear the screen (0x0E is for 'Clear Screen' functionality in int 0x30)
|
||||||
push 1
|
int 0x30 ## BIOS Video Interrupt
|
||||||
call R5
|
no_clear_screen:
|
||||||
push 0
|
|
||||||
call $testinttest
|
## Print counter
|
||||||
debug_break
|
mov R9, R1 ## Pass the counter as parameter to int 0x30
|
||||||
mov [$rect.y], 0x0000
|
mov R10, 0x05 ## 0x05 is for 'Store Integer in buffer' functionality in int 0x30
|
||||||
## debug_break
|
int 0x30 ## BIOS Video Interrupt
|
||||||
jmp $begin
|
|
||||||
push $string
|
## Print a space
|
||||||
push 1
|
mov R9, 32 ## Pass 32 (space character in ASCII) as parameter to int 0x30
|
||||||
call $strlen
|
mov R10, 0x06 ## 0x06 is for 'Store Character in buffer' functionality in int 0x30
|
||||||
mov R1, RV
|
int 0x30 ## BIOS Video Interrupt
|
||||||
mov IP, 0x0001
|
|
||||||
mov R1, RV
|
## Print the string
|
||||||
|
mov R9, $string ## Pass the address of the string as parameter to int 0x30
|
||||||
|
mov R10, 0x0A ## 0x0A is for 'Store String in buffer' functionality in int 0x30
|
||||||
|
int 0x30 ## BIOS Video Interrupt
|
||||||
|
|
||||||
|
## Print a new-line character
|
||||||
|
mov R10, 0x02 ## 0x02 is for 'Print New-Line' functionality in int 0x30
|
||||||
|
## Printing a new line when in Text-Single-Color Mode also
|
||||||
|
## prints and flushes the buffer
|
||||||
|
int 0x30 ## BIOS Video Interrupt
|
||||||
|
|
||||||
|
jmp $infinite_loop ## jump to the beginning of infinite loop
|
||||||
hlt
|
hlt
|
||||||
|
|
||||||
|
|
||||||
testinttest:
|
|
||||||
push 0
|
|
||||||
call $inttest
|
|
||||||
ret
|
|
||||||
|
|
||||||
inttest:
|
|
||||||
push 0
|
|
||||||
call $testint
|
|
||||||
ret
|
|
||||||
|
|
||||||
testint:
|
|
||||||
push 0
|
|
||||||
call $test_int
|
|
||||||
ret
|
|
||||||
|
|
||||||
test_int:
|
|
||||||
push 0
|
|
||||||
call $int_test
|
|
||||||
ret
|
|
||||||
|
|
||||||
int_test:
|
|
||||||
nop
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
strlen:
|
|
||||||
arg R1
|
|
||||||
mov R2, 0
|
|
||||||
loop:
|
|
||||||
movb ACC, *R1
|
|
||||||
inc R1
|
|
||||||
jeq $loop_end, 0
|
|
||||||
not_zero:
|
|
||||||
inc R2
|
|
||||||
jmp $loop
|
|
||||||
loop_end:
|
|
||||||
mov RV, R2
|
|
||||||
ret
|
|
||||||
|
|
||||||
.fixed 512, 0x00
|
.fixed 512, 0x00
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
##=================================================================================================================================
|
##=================================================================================================================================
|
||||||
## This is the test program for the Dragon Virtual Machine. The example has two subroutines: One is the $strlen subroutine,
|
## This is the test1 program for the Dragon Virtual Machine. The example has two subroutines: One is the $strlen subroutine,
|
||||||
## which calculates the length of the string passed as a parameter; The other calculates the fibonacci sequence up to the
|
## which calculates the length of the string passed as a parameter; The other calculates the fibonacci sequence up to the
|
||||||
## Nth number (N being the parameter passed to the subroutine).
|
## Nth number (N being the parameter passed to the subroutine).
|
||||||
## In the main part of the .code section, debug_break instructions are used in order to pause the debugger, so that the
|
## In the main part of the .code section, debug_break instructions are used in order to pause the debugger, so that the
|
||||||
48
extra/dss/test2.dss
Normal file
48
extra/dss/test2.dss
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
##=================================================================================================================================
|
||||||
|
## This is the test2 program for the Dragon Virtual Machine. This example simply demonstrates the Virtual Display in Text-Single-Color
|
||||||
|
## mode, by printing an increasing counter followed by whatever is in the $string variable. The program also clears the screen
|
||||||
|
## every 10 lines.
|
||||||
|
##=================================================================================================================================
|
||||||
|
|
||||||
|
.load 0x1740
|
||||||
|
|
||||||
|
.data
|
||||||
|
$string "Hello World!!"
|
||||||
|
|
||||||
|
.code
|
||||||
|
mov R1, 99 ## Zero the counter
|
||||||
|
infinite_loop:
|
||||||
|
inc R1 ## Increment the counter
|
||||||
|
div R1, 10 ## Divide the counter by 10
|
||||||
|
mov ACC, RV
|
||||||
|
jne $no_clear_screen, 0 ## If reminder not zero, keep going
|
||||||
|
mov R10, 0xE0 ## Else clear the screen (0x0E is for 'Clear Screen' functionality in int 0x30)
|
||||||
|
int 0x30 ## BIOS Video Interrupt
|
||||||
|
no_clear_screen:
|
||||||
|
|
||||||
|
## Print counter
|
||||||
|
mov R9, R1 ## Pass the counter as parameter to int 0x30
|
||||||
|
mov R10, 0x05 ## 0x05 is for 'Store Integer in buffer' functionality in int 0x30
|
||||||
|
int 0x30 ## BIOS Video Interrupt
|
||||||
|
|
||||||
|
## Print a space
|
||||||
|
mov R9, 32 ## Pass 32 (space character in ASCII) as parameter to int 0x30
|
||||||
|
mov R10, 0x06 ## 0x06 is for 'Store Character in buffer' functionality in int 0x30
|
||||||
|
int 0x30 ## BIOS Video Interrupt
|
||||||
|
|
||||||
|
## Print the string
|
||||||
|
mov R9, $string ## Pass the address of the string as parameter to int 0x30
|
||||||
|
mov R10, 0x0A ## 0x0A is for 'Store String in buffer' functionality in int 0x30
|
||||||
|
int 0x30 ## BIOS Video Interrupt
|
||||||
|
|
||||||
|
## Print a new-line character
|
||||||
|
mov R10, 0x02 ## 0x02 is for 'Print New-Line' functionality in int 0x30
|
||||||
|
## Printing a new line when in Text-Single-Color Mode also
|
||||||
|
## prints and flushes the buffer
|
||||||
|
int 0x30 ## BIOS Video Interrupt
|
||||||
|
|
||||||
|
jmp $infinite_loop ## jump to the beginning of infinite loop
|
||||||
|
hlt
|
||||||
|
|
||||||
|
|
||||||
|
.fixed 512, 0x00
|
||||||
BIN
extra/font_big.bmp
Normal file
BIN
extra/font_big.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 429 KiB |
13
extra/make
Normal file
13
extra/make
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
green='\033[0;32m'
|
||||||
|
clear='\033[0m'
|
||||||
|
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
printf "${green}\n=================================================================================================================\n\n"
|
||||||
25
extra/make_and_debug
Normal file
25
extra/make_and_debug
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
green='\033[0;32m'
|
||||||
|
clear='\033[0m'
|
||||||
|
|
||||||
|
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
|
||||||
|
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/newTest.dss -o newTest.bin --save-disassembly disassembly/newTest.dds --verbose
|
||||||
|
printf "\n${green}Running Application...\n\n${clear}"
|
||||||
|
./ddb config/testMachine.dvm --force-load newTest.bin 0x00 --verbose-load
|
||||||
|
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||||
|
cp dragon/cmos.dr ../extra/dragon/cmos.dr
|
||||||
|
fi
|
||||||
|
|
@ -19,8 +19,7 @@ if [ $? -eq 0 ]; then
|
||||||
printf "${green}Compiling Test Program...\n"
|
printf "${green}Compiling Test Program...\n"
|
||||||
./dasm dss/newTest.dss -o newTest.bin --save-disassembly disassembly/newTest.dds --verbose
|
./dasm dss/newTest.dss -o newTest.bin --save-disassembly disassembly/newTest.dds --verbose
|
||||||
printf "\n${green}Running Application...\n\n${clear}"
|
printf "\n${green}Running Application...\n\n${clear}"
|
||||||
./ddb config/testMachine.dvm --force-load newTest.bin 0x00 --verbose-load --hide-vdisplay
|
./dvm config/testMachine.dvm --force-load newTest.bin 0x00
|
||||||
# ./dvm config/testMachine.dvm --debug --force-load newTest.bin 0x00 --verbose-load
|
|
||||||
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
cp dragon/disk1.dr ../extra/dragon/disk1.dr
|
||||||
cp dragon/cmos.dr ../extra/dragon/cmos.dr
|
cp dragon/cmos.dr ../extra/dragon/cmos.dr
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,6 @@ clear='\033[0m'
|
||||||
|
|
||||||
printf "${green}Reloading BIOS...\n${clear}"
|
printf "${green}Reloading BIOS...\n${clear}"
|
||||||
cd ..
|
cd ..
|
||||||
cp ../extra/dss/bios.dss ./dss/bios.dss
|
cp ../extra/dss/bios/bios.dss ./dss/bios/bios.dss
|
||||||
./dasm dss/bios.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose
|
./dasm dss/bios/bios.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose
|
||||||
cp dragon/bios.bin ../extra/dragon/bios.bin
|
cp dragon/bios.bin ../extra/dragon/bios.bin
|
||||||
|
|
|
||||||
2
extra/scripts/run-test-1.bat
Normal file
2
extra/scripts/run-test-1.bat
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
dasm dss/test1.dss -o test1.bin --save-disassembly disassembly/test1.dds --verbose
|
||||||
|
ddb config/testMachine.dvm --force-load test1.bin 0x00 --verbose-load --hide-vdisplay
|
||||||
2
extra/scripts/run-test-2.bat
Normal file
2
extra/scripts/run-test-2.bat
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
dasm dss/test2.dss -o test2.bin --save-disassembly disassembly/test2.dds --verbose
|
||||||
|
ddb config/testMachine.dvm --force-load test2.bin 0x00 --verbose-load --hide-vdisplay
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
dasm dss/test.dss -o test.bin --save-disassembly disassembly/test.dds --verbose
|
|
||||||
ddb config/testMachine.dvm --force-load test.bin 0x00 --verbose-load --hide-vdisplay
|
|
||||||
|
|
@ -128,7 +128,7 @@ namespace dragon
|
||||||
void Assembler::loadSource(ostd::String source)
|
void Assembler::loadSource(ostd::String source)
|
||||||
{
|
{
|
||||||
m_rawSource = source;
|
m_rawSource = source;
|
||||||
m_lines = ostd::String(source).tokenize("\n").getRawData();
|
m_lines = ostd::String(source.replaceAll("\t", " ")).tokenize("\n").getRawData();
|
||||||
}
|
}
|
||||||
|
|
||||||
ostd::ByteStream Assembler::assembleToFile(ostd::String sourceFileName, ostd::String binaryFileName)
|
ostd::ByteStream Assembler::assembleToFile(ostd::String sourceFileName, ostd::String binaryFileName)
|
||||||
|
|
@ -245,7 +245,7 @@ namespace dragon
|
||||||
{
|
{
|
||||||
ostd::String lineEdit(line);
|
ostd::String lineEdit(line);
|
||||||
for (int32_t i = defines.size() - 1; i >= 0; i--)
|
for (int32_t i = defines.size() - 1; i >= 0; i--)
|
||||||
lineEdit.replaceAll(defines[i].name, defines[i].value);
|
lineEdit.replaceAll(defines[i].name, defines[i].value.new_trim());
|
||||||
line = lineEdit;
|
line = lineEdit;
|
||||||
}
|
}
|
||||||
m_lines.clear();
|
m_lines.clear();
|
||||||
|
|
@ -1190,7 +1190,7 @@ namespace dragon
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (instEdit == "add" || instEdit == "sub" || instEdit == "mul")
|
else if (instEdit == "add" || instEdit == "sub" || instEdit == "mul" || instEdit == "div")
|
||||||
{
|
{
|
||||||
m_code.push_back(0x00);
|
m_code.push_back(0x00);
|
||||||
eOperandType opType = parseOperand(st.next(), word);
|
eOperandType opType = parseOperand(st.next(), word);
|
||||||
|
|
@ -1208,6 +1208,7 @@ namespace dragon
|
||||||
if (instEdit == "add") m_code[m_code.size() - 2] = data::OpCodes::AddImmReg;
|
if (instEdit == "add") m_code[m_code.size() - 2] = data::OpCodes::AddImmReg;
|
||||||
else if (instEdit == "sub") m_code[m_code.size() - 2] = data::OpCodes::SubImmReg;
|
else if (instEdit == "sub") m_code[m_code.size() - 2] = data::OpCodes::SubImmReg;
|
||||||
else if (instEdit == "mul") m_code[m_code.size() - 2] = data::OpCodes::MulImmReg;
|
else if (instEdit == "mul") m_code[m_code.size() - 2] = data::OpCodes::MulImmReg;
|
||||||
|
else if (instEdit == "div") m_code[m_code.size() - 2] = data::OpCodes::DivImmReg;
|
||||||
m_code.push_back((uint8_t)((word & 0xFF00) >> 8));
|
m_code.push_back((uint8_t)((word & 0xFF00) >> 8));
|
||||||
m_code.push_back((uint8_t)(word & 0x00FF));
|
m_code.push_back((uint8_t)(word & 0x00FF));
|
||||||
}
|
}
|
||||||
|
|
@ -1216,6 +1217,7 @@ namespace dragon
|
||||||
if (instEdit == "add") m_code[m_code.size() - 2] = data::OpCodes::AddRegReg;
|
if (instEdit == "add") m_code[m_code.size() - 2] = data::OpCodes::AddRegReg;
|
||||||
else if (instEdit == "sub") m_code[m_code.size() - 2] = data::OpCodes::SubRegReg;
|
else if (instEdit == "sub") m_code[m_code.size() - 2] = data::OpCodes::SubRegReg;
|
||||||
else if (instEdit == "mul") m_code[m_code.size() - 2] = data::OpCodes::MulRegReg;
|
else if (instEdit == "mul") m_code[m_code.size() - 2] = data::OpCodes::MulRegReg;
|
||||||
|
else if (instEdit == "div") m_code[m_code.size() - 2] = data::OpCodes::DivRegReg;
|
||||||
m_code.push_back((uint8_t)word);
|
m_code.push_back((uint8_t)word);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1435,6 +1437,26 @@ namespace dragon
|
||||||
return eOperandType::DerefRegister;
|
return eOperandType::DerefRegister;
|
||||||
return eOperandType::Register;
|
return eOperandType::Register;
|
||||||
}
|
}
|
||||||
|
else if (opEdit.startsWith("reg(") && opEdit.endsWith(")"))
|
||||||
|
{
|
||||||
|
opEdit.substr(4, opEdit.len() - 1);
|
||||||
|
opEdit.trim();
|
||||||
|
if (!opEdit.isNumeric())
|
||||||
|
{
|
||||||
|
std::cout << "Invalid numeric value: " << opEdit << "\n";
|
||||||
|
return eOperandType::Error;
|
||||||
|
}
|
||||||
|
uint8_t _reg = opEdit.toInt();
|
||||||
|
if (_reg >= data::Registers::Last)
|
||||||
|
{
|
||||||
|
std::cout << "Invalid Register: " << opEdit << "\n";
|
||||||
|
return eOperandType::Error;
|
||||||
|
}
|
||||||
|
outOp = (int16_t)_reg;
|
||||||
|
if (derefReg)
|
||||||
|
return eOperandType::DerefRegister;
|
||||||
|
return eOperandType::Register;
|
||||||
|
}
|
||||||
if (derefReg)
|
if (derefReg)
|
||||||
{
|
{
|
||||||
std::cout << "Invalid Register Dereferencing: " << op << "\n";
|
std::cout << "Invalid Register Dereferencing: " << op << "\n";
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ namespace dragon
|
||||||
{
|
{
|
||||||
validate();
|
validate();
|
||||||
enableSignals();
|
enableSignals();
|
||||||
connectSignal(dragon::Window::Signal_OnWindowClosed);
|
connectSignal(ostd::tBuiltinSignals::WindowClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::tCloseEventListener::handleSignal(ostd::tSignal& signal)
|
void Debugger::tCloseEventListener::handleSignal(ostd::tSignal& signal)
|
||||||
{
|
{
|
||||||
m_mainWindowClosed = signal.ID == dragon::Window::Signal_OnWindowClosed;
|
m_mainWindowClosed = signal.ID == ostd::tBuiltinSignals::WindowClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1290,6 +1290,11 @@ namespace dragon
|
||||||
data().args.step_exec = !data().args.step_exec;
|
data().args.step_exec = !data().args.step_exec;
|
||||||
output().p("Step execution = ").p(STR_BOOL(data().args.step_exec)).nl();
|
output().p("Step execution = ").p(STR_BOOL(data().args.step_exec)).nl();
|
||||||
}
|
}
|
||||||
|
else if (data().command == "display")
|
||||||
|
{
|
||||||
|
data().args.hide_virtual_display = !data().args.hide_virtual_display;
|
||||||
|
output().p("Virtual Display Hidden = ").p(STR_BOOL(data().args.hide_virtual_display)).nl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1526,6 +1531,9 @@ namespace dragon
|
||||||
tmpCommand = "(t)rack <address[bytes=1]/symbol>";
|
tmpCommand = "(t)rack <address[bytes=1]/symbol>";
|
||||||
tmpCommand.addRightPadding(commandLength);
|
tmpCommand.addRightPadding(commandLength);
|
||||||
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to track specific addresses during execution.").reset().nl();
|
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to track specific addresses during execution.").reset().nl();
|
||||||
|
tmpCommand = "display";
|
||||||
|
tmpCommand.addRightPadding(commandLength);
|
||||||
|
out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to enable/disable the Virtual Display for the runtime.").reset().nl();
|
||||||
|
|
||||||
out.nl().fg(ostd::ConsoleColors::Cyan).p("The letters in parenthesis can be used as the short version of the command.").nl();
|
out.nl().fg(ostd::ConsoleColors::Cyan).p("The letters in parenthesis can be used as the short version of the command.").nl();
|
||||||
out.p("Square brackets represent optional parameters. If they have an '=' and a value, that is the default if not specified.").reset().nl();
|
out.p("Square brackets represent optional parameters. If they have an '=' and a value, that is the default if not specified.").reset().nl();
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace dragon
|
||||||
bool step_exec = false;
|
bool step_exec = false;
|
||||||
bool track_step_diff = true;
|
bool track_step_diff = true;
|
||||||
bool auto_start_debug = false;
|
bool auto_start_debug = false;
|
||||||
bool hide_virtual_display = false;
|
bool hide_virtual_display = true;
|
||||||
bool track_call_stack = true;
|
bool track_call_stack = true;
|
||||||
bool auto_track_all_data_symbols = true;
|
bool auto_track_all_data_symbols = true;
|
||||||
ostd::String force_load_file = "";
|
ostd::String force_load_file = "";
|
||||||
|
|
|
||||||
70
src/gui/Renderer.cpp
Normal file
70
src/gui/Renderer.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include "Renderer.hpp"
|
||||||
|
#include "Window.hpp"
|
||||||
|
#include <ostd/Utils.hpp>
|
||||||
|
|
||||||
|
namespace dragon
|
||||||
|
{
|
||||||
|
Renderer::~Renderer(void)
|
||||||
|
{
|
||||||
|
if (isInvalid()) return;
|
||||||
|
ostd::Utils::destroyArray(m_pixels);
|
||||||
|
SDL_DestroyTexture(m_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::initialize(Window& parent)
|
||||||
|
{
|
||||||
|
if (isValid()) return; //TODO: Error
|
||||||
|
if (!parent.isValid() || !parent.isInitialized())
|
||||||
|
return; //TODO: Error
|
||||||
|
m_parent = &parent;
|
||||||
|
m_pixels = ostd::Utils::createArray<uint32_t>(parent.getWindowWidth() * parent.getWindowHeight());
|
||||||
|
m_texture = SDL_CreateTexture(parent.getSDLRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, parent.getWindowWidth(), parent.getWindowHeight());
|
||||||
|
m_windowWidth = parent.getWindowWidth();
|
||||||
|
m_windowHeight = parent.getWindowHeight();
|
||||||
|
setTypeName("lspp::gfx::Renderer");
|
||||||
|
enableSignals();
|
||||||
|
connectSignal(ostd::tBuiltinSignals::WindowResized);
|
||||||
|
validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::handleSignal(ostd::tSignal& signal)
|
||||||
|
{
|
||||||
|
if (isInvalid()) return;
|
||||||
|
if (signal.ID == ostd::tBuiltinSignals::WindowResized)
|
||||||
|
{
|
||||||
|
m_pixels = ostd::Utils::resizeArray<uint32_t>(m_pixels, m_parent->getWindowWidth() * m_parent->getWindowHeight());
|
||||||
|
SDL_DestroyTexture(m_texture);
|
||||||
|
m_texture = SDL_CreateTexture(m_parent->getSDLRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, m_parent->getWindowWidth(), m_parent->getWindowHeight());
|
||||||
|
m_windowWidth = m_parent->getWindowWidth();
|
||||||
|
m_windowHeight = m_parent->getWindowHeight();
|
||||||
|
updateBuffer();
|
||||||
|
displayBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::updateBuffer(void)
|
||||||
|
{
|
||||||
|
if (isInvalid()) return;
|
||||||
|
SDL_UpdateTexture(m_texture, NULL, m_pixels, m_windowWidth * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::displayBuffer(void)
|
||||||
|
{
|
||||||
|
if (isInvalid()) return;
|
||||||
|
SDL_Rect rect { 0, 0, m_windowWidth, m_windowHeight };
|
||||||
|
SDL_RenderCopy(m_parent->getSDLRenderer(), m_texture, NULL, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::clear(const ostd::Color& color)
|
||||||
|
{
|
||||||
|
if (isInvalid()) return;
|
||||||
|
for (int32_t y = 0; y < m_windowHeight; y++)
|
||||||
|
{
|
||||||
|
for (uint32_t x = 0; x < m_windowWidth; x++)
|
||||||
|
{
|
||||||
|
int32_t index = CONVERT_2D_1D(x, y, m_windowWidth);
|
||||||
|
m_pixels[index] = color.asInteger();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/gui/Renderer.hpp
Normal file
29
src/gui/Renderer.hpp
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ostd/Color.hpp>
|
||||||
|
#include "../tools/SDLInclude.hpp"
|
||||||
|
|
||||||
|
namespace dragon
|
||||||
|
{
|
||||||
|
class Window;
|
||||||
|
class Renderer : public ostd::BaseObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline Renderer(void) { invalidate(); }
|
||||||
|
~Renderer(void);
|
||||||
|
void initialize(Window& parent);
|
||||||
|
void handleSignal(ostd::tSignal& signal) override;
|
||||||
|
void updateBuffer(void);
|
||||||
|
void displayBuffer(void);
|
||||||
|
inline uint32_t* getScreenPixels(void) { return m_pixels; }
|
||||||
|
|
||||||
|
void clear(const ostd::Color& color);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t* m_pixels { nullptr };
|
||||||
|
SDL_Texture* m_texture { nullptr };
|
||||||
|
Window* m_parent { nullptr };
|
||||||
|
int32_t m_windowWidth { 0 };
|
||||||
|
int32_t m_windowHeight { 0 };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -54,8 +54,9 @@ namespace dragon
|
||||||
if (!m_initialized) return;
|
if (!m_initialized) return;
|
||||||
Uint64 start = SDL_GetPerformanceCounter();
|
Uint64 start = SDL_GetPerformanceCounter();
|
||||||
handleEvents();
|
handleEvents();
|
||||||
onUpdate();
|
if (m_refreshScreen)
|
||||||
SDL_RenderClear(m_renderer);
|
SDL_RenderClear(m_renderer);
|
||||||
|
onUpdate();
|
||||||
onRender();
|
onRender();
|
||||||
SDL_RenderPresent(m_renderer);
|
SDL_RenderPresent(m_renderer);
|
||||||
Uint64 end = SDL_GetPerformanceCounter();
|
Uint64 end = SDL_GetPerformanceCounter();
|
||||||
|
|
@ -81,6 +82,7 @@ namespace dragon
|
||||||
{
|
{
|
||||||
if (!isInitialized()) return;
|
if (!isInitialized()) return;
|
||||||
SDL_SetWindowSize(m_window, width, height);
|
SDL_SetWindowSize(m_window, width, height);
|
||||||
|
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::WindowResized, ostd::tSignalPriority::RealTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setTitle(const ostd::String& title)
|
void Window::setTitle(const ostd::String& title)
|
||||||
|
|
@ -113,7 +115,7 @@ namespace dragon
|
||||||
if (event.type == SDL_QUIT)
|
if (event.type == SDL_QUIT)
|
||||||
{
|
{
|
||||||
m_running = false;
|
m_running = false;
|
||||||
ostd::SignalHandler::emitSignal(Signal_OnWindowClosed, ostd::tSignalPriority::Normal, *this);
|
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::WindowClosed, ostd::tSignalPriority::Normal, *this);
|
||||||
}
|
}
|
||||||
else if (event.type == SDL_WINDOWEVENT)
|
else if (event.type == SDL_WINDOWEVENT)
|
||||||
{
|
{
|
||||||
|
|
@ -129,7 +131,7 @@ namespace dragon
|
||||||
{
|
{
|
||||||
MouseEventData mmd = l_getMouseState();
|
MouseEventData mmd = l_getMouseState();
|
||||||
if (isMouseDragEventEnabled() && mmd.button != MouseEventData::eButton::None)
|
if (isMouseDragEventEnabled() && mmd.button != MouseEventData::eButton::None)
|
||||||
ostd::SignalHandler::emitSignal(Signal_OnMouseDragged, ostd::tSignalPriority::RealTime, mmd);
|
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::WindowClosed, ostd::tSignalPriority::RealTime, mmd);
|
||||||
else
|
else
|
||||||
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::MouseMoved, ostd::tSignalPriority::RealTime, mmd);
|
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::MouseMoved, ostd::tSignalPriority::RealTime, mmd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ namespace dragon
|
||||||
SDL_Surface* m_fontSurface { nullptr };
|
SDL_Surface* m_fontSurface { nullptr };
|
||||||
uint32_t* m_fontPixels { nullptr };
|
uint32_t* m_fontPixels { nullptr };
|
||||||
|
|
||||||
|
bool m_refreshScreen { true };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32_t m_windowWidth { 0 };
|
int32_t m_windowWidth { 0 };
|
||||||
int32_t m_windowHeight { 0 };
|
int32_t m_windowHeight { 0 };
|
||||||
|
|
@ -61,11 +63,6 @@ namespace dragon
|
||||||
bool m_deagEventEnabled { false };
|
bool m_deagEventEnabled { false };
|
||||||
bool m_running { false };
|
bool m_running { false };
|
||||||
bool m_initialized { false };
|
bool m_initialized { false };
|
||||||
|
|
||||||
public:
|
|
||||||
//Signals //TODO: Add theese to the builtin signals in ostd::SignalHandler
|
|
||||||
inline static const uint32_t Signal_OnMouseDragged = ostd::SignalHandler::newCustomSignal(1003);
|
|
||||||
inline static const uint32_t Signal_OnWindowClosed = ostd::SignalHandler::newCustomSignal(2000);
|
|
||||||
};
|
};
|
||||||
class WindowResizedData : public ostd::BaseObject
|
class WindowResizedData : public ostd::BaseObject
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -413,6 +413,29 @@ namespace dragon
|
||||||
writeRegister(data::Registers::ACC, regValue1 * regValue2);
|
writeRegister(data::Registers::ACC, regValue1 * regValue2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case data::OpCodes::DivImmReg: //TODO: Division by zero is unhandled
|
||||||
|
{
|
||||||
|
uint8_t regAddr = fetch8();
|
||||||
|
int16_t literal = fetch16();
|
||||||
|
int16_t regValue = readRegister(regAddr);
|
||||||
|
int16_t quotient = regValue / literal;
|
||||||
|
int16_t reminder = regValue % literal;
|
||||||
|
writeRegister(data::Registers::ACC, quotient);
|
||||||
|
writeRegister(data::Registers::RV, reminder);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case data::OpCodes::DivRegReg: //TODO: Division by zero is unhandled
|
||||||
|
{
|
||||||
|
uint8_t regAddr1 = fetch8();
|
||||||
|
uint8_t regAddr2 = fetch8();
|
||||||
|
int16_t regValue1 = readRegister(regAddr1);
|
||||||
|
int16_t regValue2 = readRegister(regAddr2);
|
||||||
|
int16_t quotient = regValue1 / regValue2;
|
||||||
|
int16_t reminder = regValue1 % regValue2;
|
||||||
|
writeRegister(data::Registers::ACC, quotient);
|
||||||
|
writeRegister(data::Registers::RV, reminder);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case data::OpCodes::IncReg:
|
case data::OpCodes::IncReg:
|
||||||
{
|
{
|
||||||
uint8_t regAddr = fetch8();
|
uint8_t regAddr = fetch8();
|
||||||
|
|
|
||||||
158
src/hardware/VirtualDisplay.cpp
Normal file
158
src/hardware/VirtualDisplay.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
#include "VirtualDisplay.hpp"
|
||||||
|
#include "../gui/RawTextRenderer.hpp"
|
||||||
|
#include "../runtime/DragonRuntime.hpp"
|
||||||
|
|
||||||
|
namespace dragon
|
||||||
|
{
|
||||||
|
namespace hw
|
||||||
|
{
|
||||||
|
void VirtualDisplay::onInitialize(void)
|
||||||
|
{
|
||||||
|
m_renderer.initialize(*this);
|
||||||
|
RawTextRenderer::initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualDisplay::onDestroy(void) { }
|
||||||
|
|
||||||
|
void VirtualDisplay::onRender(void)
|
||||||
|
{
|
||||||
|
auto& config = DragonRuntime::machine_config;
|
||||||
|
if (m_refreshScreen)
|
||||||
|
{
|
||||||
|
m_renderer.clear(config.singleColor_background);
|
||||||
|
for (int32_t i = 0; i < m_singleTextLines.size(); i++)
|
||||||
|
{
|
||||||
|
auto& line = m_singleTextLines[i];
|
||||||
|
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground);
|
||||||
|
}
|
||||||
|
m_refreshScreen = false;
|
||||||
|
}
|
||||||
|
m_renderer.updateBuffer();
|
||||||
|
m_renderer.displayBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualDisplay::onUpdate(void)
|
||||||
|
{
|
||||||
|
auto& mem = DragonRuntime::memMap;
|
||||||
|
uint16_t vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
|
||||||
|
uint8_t video_mode = mem.read8(vga_addr + tRegisters::VideoMode);
|
||||||
|
uint8_t 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_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 return;
|
||||||
|
mem.write8(vga_addr + tRegisters::Signal, tSignalValues::Continue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualDisplay::onFixedUpdate(void) { }
|
||||||
|
|
||||||
|
void VirtualDisplay::onSlowUpdate(void) { }
|
||||||
|
|
||||||
|
void VirtualDisplay::single_text_add_char_to_line(char c)
|
||||||
|
{
|
||||||
|
auto& config = DragonRuntime::machine_config;
|
||||||
|
if (m_singleTextLines.size() == 0)
|
||||||
|
{
|
||||||
|
m_singleTextLines.push_back(ostd::String().addChar(c));
|
||||||
|
RawTextRenderer::drawString(ostd::String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
|
||||||
|
if (c == '\n')
|
||||||
|
m_singleTextLines.push_back("");
|
||||||
|
else if (isprint(c))
|
||||||
|
{
|
||||||
|
if (line.len() == RawTextRenderer::CONSOLE_CHARS_H)
|
||||||
|
{
|
||||||
|
m_singleTextLines.push_back(ostd::String().addChar(c));
|
||||||
|
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
|
||||||
|
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line.addChar(c);
|
||||||
|
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
if (m_singleTextLines.size() == RawTextRenderer::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() == RawTextRenderer::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/hardware/VirtualDisplay.hpp
Normal file
60
src/hardware/VirtualDisplay.hpp
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../gui/Window.hpp"
|
||||||
|
#include "../gui/Renderer.hpp"
|
||||||
|
|
||||||
|
namespace dragon
|
||||||
|
{
|
||||||
|
namespace hw
|
||||||
|
{
|
||||||
|
class VirtualDisplay : public Window
|
||||||
|
{
|
||||||
|
public: struct tRegisters
|
||||||
|
{
|
||||||
|
inline static constexpr uint8_t VideoMode = 0x00;
|
||||||
|
inline static constexpr uint8_t Signal = 0x03;
|
||||||
|
inline static constexpr uint8_t TextSingleCharacter = 0x04;
|
||||||
|
};
|
||||||
|
public: struct tVideoModeValues
|
||||||
|
{
|
||||||
|
inline static constexpr uint8_t TextSingleColor = 0x00;
|
||||||
|
};
|
||||||
|
public: struct tSignalValues
|
||||||
|
{
|
||||||
|
inline static constexpr uint8_t Continue = 0x00;
|
||||||
|
|
||||||
|
inline static constexpr uint8_t TextSingleColor_DirectPrintChar = 0x02;
|
||||||
|
inline static constexpr uint8_t TextSingleColor_StoreChar = 0x03;
|
||||||
|
inline static constexpr uint8_t TextSingleColor_DirectPrintBuffAndFlush = 0x04;
|
||||||
|
inline static constexpr uint8_t TextSingleColor_FlushBuffer = 0x05;
|
||||||
|
inline static constexpr uint8_t TextSingleColor_DirectPrintBuffNoFlush = 0x06;
|
||||||
|
|
||||||
|
inline static constexpr uint8_t RefreshScreen = 0xE0;
|
||||||
|
inline static constexpr uint8_t ClearSCreen = 0xE1;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
void onInitialize(void) override;
|
||||||
|
void onDestroy(void) override;
|
||||||
|
void onRender(void) override;
|
||||||
|
void onUpdate(void) override;
|
||||||
|
void onFixedUpdate(void) override;
|
||||||
|
void onSlowUpdate(void) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
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);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Renderer m_renderer;
|
||||||
|
|
||||||
|
std::vector<ostd::String> m_singleTextLines;
|
||||||
|
ostd::String m_singleTextBuffer { "" };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -438,31 +438,54 @@ namespace dragon
|
||||||
|
|
||||||
Graphics::Graphics(void)
|
Graphics::Graphics(void)
|
||||||
{
|
{
|
||||||
|
m_videoMemory.init(0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t Graphics::read8(uint16_t addr)
|
int8_t Graphics::read8(uint16_t addr)
|
||||||
{
|
{
|
||||||
return 0x00;
|
int8_t 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)
|
int16_t Graphics::read16(uint16_t addr)
|
||||||
{
|
{
|
||||||
return 0x0000;
|
int16_t 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)
|
int8_t Graphics::write8(uint16_t addr, int8_t 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)
|
int16_t Graphics::write16(uint16_t addr, int16_t value)
|
||||||
{
|
{
|
||||||
return 0x0000;
|
if (!m_videoMemory.w_Word(addr, value))
|
||||||
|
{
|
||||||
|
data::ErrorHandler::pushError(data::ErrorCodes::Graphics_MemoryWriteFailed, "Failed to word byte to Graphics Memory");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostd::ByteStream* Graphics::getByteStream(void)
|
ostd::ByteStream* Graphics::getByteStream(void)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return &m_videoMemory.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,7 @@ namespace dragon
|
||||||
ostd::ByteStream* getByteStream(void) override;
|
ostd::ByteStream* getByteStream(void) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ostd::serial::SerialIO m_videoMemory;
|
||||||
};
|
};
|
||||||
class SerialPort : public IMemoryDevice
|
class SerialPort : public IMemoryDevice
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,16 @@ namespace dragon
|
||||||
lineEdit = tokens.next();
|
lineEdit = tokens.next();
|
||||||
config.cmos_path = lineEdit;
|
config.cmos_path = lineEdit;
|
||||||
}
|
}
|
||||||
|
else if (lineEdit == "singlecolor_foreground")
|
||||||
|
{
|
||||||
|
lineEdit = tokens.next();
|
||||||
|
config.singleColor_foreground.set(lineEdit);
|
||||||
|
}
|
||||||
|
else if (lineEdit == "singlecolor_background")
|
||||||
|
{
|
||||||
|
lineEdit = tokens.next();
|
||||||
|
config.singleColor_background.set(lineEdit);
|
||||||
|
}
|
||||||
else continue; //TODO: Warning
|
else continue; //TODO: Warning
|
||||||
}
|
}
|
||||||
return validate_machine_config(config);
|
return validate_machine_config(config);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ostd/String.hpp>
|
#include <ostd/Color.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace dragon
|
namespace dragon
|
||||||
|
|
@ -10,6 +10,8 @@ namespace dragon
|
||||||
std::map<int32_t, ostd::String> vdisk_paths;
|
std::map<int32_t, ostd::String> vdisk_paths;
|
||||||
ostd::String bios_path;
|
ostd::String bios_path;
|
||||||
ostd::String cmos_path;
|
ostd::String cmos_path;
|
||||||
|
ostd::Color singleColor_background;
|
||||||
|
ostd::Color singleColor_foreground;
|
||||||
|
|
||||||
inline bool isValid(void) const { return m_valid; }
|
inline bool isValid(void) const { return m_valid; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,10 +136,9 @@ namespace dragon
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
out.fg(ostd::ConsoleColors::Magenta).p(" Initializing virtual display:").nl();
|
out.fg(ostd::ConsoleColors::Magenta).p(" Initializing virtual display:").nl();
|
||||||
vDisplay.initialize(800, 600, "DragonVM", "font.bmp");
|
|
||||||
int32_t w = RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::FONT_CHAR_W; //60 * 16;
|
int32_t w = RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::FONT_CHAR_W; //60 * 16;
|
||||||
int32_t h = RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::FONT_CHAR_H; //60 * 9;
|
int32_t h = RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::FONT_CHAR_H; //60 * 9;
|
||||||
vDisplay.setSize(w, h);
|
vDisplay.initialize(w, h, "DragonVM", "font.bmp");
|
||||||
if (hideVirtualDisplay)
|
if (hideVirtualDisplay)
|
||||||
vDisplay.hide();
|
vDisplay.hide();
|
||||||
if (verbose)
|
if (verbose)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "../hardware/VirtualRAM.hpp"
|
#include "../hardware/VirtualRAM.hpp"
|
||||||
#include "../hardware/VirtualIODevices.hpp"
|
#include "../hardware/VirtualIODevices.hpp"
|
||||||
#include "../hardware/VirtualHardDrive.hpp"
|
#include "../hardware/VirtualHardDrive.hpp"
|
||||||
|
#include "../hardware/VirtualDisplay.hpp"
|
||||||
|
|
||||||
#include "../tools/GlobalData.hpp"
|
#include "../tools/GlobalData.hpp"
|
||||||
|
|
||||||
|
|
@ -73,7 +74,7 @@ namespace dragon
|
||||||
std::vector<tCallInfo> callStack;
|
std::vector<tCallInfo> callStack;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
static void printRegisters(dragon::hw::VirtualCPU& cpu);
|
static void printRegisters(hw::VirtualCPU& cpu);
|
||||||
static void processErrors(void);
|
static void processErrors(void);
|
||||||
static std::vector<data::ErrorHandler::tError> getErrorList(void);
|
static std::vector<data::ErrorHandler::tError> getErrorList(void);
|
||||||
static int32_t loadArguments(int argc, char** argv, tCommandLineArgs& args);
|
static int32_t loadArguments(int argc, char** argv, tCommandLineArgs& args);
|
||||||
|
|
@ -99,24 +100,24 @@ namespace dragon
|
||||||
public:
|
public:
|
||||||
inline static ostd::ConsoleOutputHandler out;
|
inline static ostd::ConsoleOutputHandler out;
|
||||||
|
|
||||||
inline static dragon::hw::MemoryMapper memMap;
|
inline static hw::MemoryMapper memMap;
|
||||||
inline static dragon::hw::VirtualCPU cpu { memMap };
|
inline static hw::VirtualCPU cpu { memMap };
|
||||||
inline static dragon::hw::VirtualRAM ram;
|
inline static hw::VirtualRAM ram;
|
||||||
inline static dragon::hw::InterruptVector intVec;
|
inline static hw::InterruptVector intVec;
|
||||||
inline static dragon::hw::VirtualBIOS vBIOS;
|
inline static hw::VirtualBIOS vBIOS;
|
||||||
inline static dragon::hw::interface::CMOS vCMOS;
|
inline static hw::interface::CMOS vCMOS;
|
||||||
inline static dragon::hw::VirtualBootloader vMBR;
|
inline static hw::VirtualBootloader vMBR;
|
||||||
inline static dragon::hw::VirtualKeyboard vKeyboard;
|
inline static hw::VirtualKeyboard vKeyboard;
|
||||||
inline static dragon::hw::VirtualMouse vMouse;
|
inline static hw::VirtualMouse vMouse;
|
||||||
inline static dragon::hw::interface::Disk vDiskInterface { memMap, cpu };
|
inline static hw::interface::Disk vDiskInterface { memMap, cpu };
|
||||||
inline static dragon::hw::interface::Graphics vGraphicsInterface;
|
inline static hw::interface::Graphics vGraphicsInterface;
|
||||||
inline static dragon::hw::interface::SerialPort vSerialInterface;
|
inline static hw::interface::SerialPort vSerialInterface;
|
||||||
|
|
||||||
inline static std::unordered_map<int32_t, dragon::hw::VirtualHardDrive> vDisks;
|
inline static std::unordered_map<int32_t, hw::VirtualHardDrive> vDisks;
|
||||||
|
|
||||||
inline static dragon::Window vDisplay;
|
inline static hw::VirtualDisplay vDisplay;
|
||||||
|
|
||||||
inline static dragon::tMachineConfig machine_config;
|
inline static tMachineConfig machine_config;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static tMachineDebugInfo s_machineInfo;
|
inline static tMachineDebugInfo s_machineInfo;
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ namespace dragon
|
||||||
|
|
||||||
inline static constexpr uint64_t IntVector_InvalidAddress = 0x7000000000000000;
|
inline static constexpr uint64_t IntVector_InvalidAddress = 0x7000000000000000;
|
||||||
|
|
||||||
|
inline static constexpr uint64_t Graphics_MemoryReadFailed = 0x8000000000000000;
|
||||||
|
inline static constexpr uint64_t Graphics_MemoryWriteFailed = 0x8000000000000001;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ErrorHandler
|
class ErrorHandler
|
||||||
|
|
@ -158,9 +161,7 @@ namespace dragon
|
||||||
inline static constexpr uint8_t PP = 0x04;
|
inline static constexpr uint8_t PP = 0x04;
|
||||||
inline static constexpr uint8_t FL = 0x05;
|
inline static constexpr uint8_t FL = 0x05;
|
||||||
inline static constexpr uint8_t ACC = 0x06;
|
inline static constexpr uint8_t ACC = 0x06;
|
||||||
|
//0x07, 0x08, 0x09 Are hidden registers used internally, but can be normally accessed by address
|
||||||
//TODO: Either add general purpose registers in this space or check when read/write registers
|
|
||||||
|
|
||||||
inline static constexpr uint8_t R1 = 0x0A;
|
inline static constexpr uint8_t R1 = 0x0A;
|
||||||
inline static constexpr uint8_t R2 = 0x0B;
|
inline static constexpr uint8_t R2 = 0x0B;
|
||||||
inline static constexpr uint8_t R3 = 0x0C;
|
inline static constexpr uint8_t R3 = 0x0C;
|
||||||
|
|
@ -184,11 +185,6 @@ namespace dragon
|
||||||
class InterruptCodes
|
class InterruptCodes
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline static constexpr uint8_t Keyboard = 0x10;
|
|
||||||
inline static constexpr uint8_t Mouse = 0x11;
|
|
||||||
inline static constexpr uint8_t BiosInterrupt = 0x20;
|
|
||||||
inline static constexpr uint8_t BiosVideoInterrupt = 0x30;
|
|
||||||
|
|
||||||
inline static constexpr uint8_t DiskInterfaceFFinished = 0x80;
|
inline static constexpr uint8_t DiskInterfaceFFinished = 0x80;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -229,6 +225,8 @@ namespace dragon
|
||||||
inline static constexpr uint8_t SubImmReg = 0x33;
|
inline static constexpr uint8_t SubImmReg = 0x33;
|
||||||
inline static constexpr uint8_t MulRegReg = 0x34;
|
inline static constexpr uint8_t MulRegReg = 0x34;
|
||||||
inline static constexpr uint8_t MulImmReg = 0x35;
|
inline static constexpr uint8_t MulImmReg = 0x35;
|
||||||
|
inline static constexpr uint8_t DivRegReg = 0x36;
|
||||||
|
inline static constexpr uint8_t DivImmReg = 0x37;
|
||||||
|
|
||||||
inline static constexpr uint8_t IncReg = 0x40;
|
inline static constexpr uint8_t IncReg = 0x40;
|
||||||
inline static constexpr uint8_t DecReg = 0x41;
|
inline static constexpr uint8_t DecReg = 0x41;
|
||||||
|
|
@ -305,6 +303,8 @@ namespace dragon
|
||||||
case data::OpCodes::SubRegReg: return "SubRegReg";
|
case data::OpCodes::SubRegReg: return "SubRegReg";
|
||||||
case data::OpCodes::MulImmReg: return "MulImmReg";
|
case data::OpCodes::MulImmReg: return "MulImmReg";
|
||||||
case data::OpCodes::MulRegReg: return "MulRegReg";
|
case data::OpCodes::MulRegReg: return "MulRegReg";
|
||||||
|
case data::OpCodes::DivImmReg: return "DivImmReg";
|
||||||
|
case data::OpCodes::DivRegReg: return "DivRegReg";
|
||||||
case data::OpCodes::IncReg: return "IncReg";
|
case data::OpCodes::IncReg: return "IncReg";
|
||||||
case data::OpCodes::DecReg: return "DecReg";
|
case data::OpCodes::DecReg: return "DecReg";
|
||||||
case data::OpCodes::RShiftRegImm: return "RShiftRegImm";
|
case data::OpCodes::RShiftRegImm: return "RShiftRegImm";
|
||||||
|
|
@ -379,6 +379,8 @@ namespace dragon
|
||||||
case data::OpCodes::SubRegReg: return 3;
|
case data::OpCodes::SubRegReg: return 3;
|
||||||
case data::OpCodes::MulImmReg: return 4;
|
case data::OpCodes::MulImmReg: return 4;
|
||||||
case data::OpCodes::MulRegReg: return 3;
|
case data::OpCodes::MulRegReg: return 3;
|
||||||
|
case data::OpCodes::DivImmReg: return 4;
|
||||||
|
case data::OpCodes::DivRegReg: return 3;
|
||||||
case data::OpCodes::IncReg: return 2;
|
case data::OpCodes::IncReg: return 2;
|
||||||
case data::OpCodes::DecReg: return 2;
|
case data::OpCodes::DecReg: return 2;
|
||||||
case data::OpCodes::RShiftRegImm: return 4;
|
case data::OpCodes::RShiftRegImm: return 4;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue