Added .entry directive to DASM

This commit is contained in:
OmniaX 2024-09-15 12:28:48 +02:00
parent 8d35484a20
commit bf4662e4b4
28 changed files with 166 additions and 1141 deletions

View file

@ -7,6 +7,8 @@ fixed_clock = false
clock_rate_sec = 2000
memory_extension_pages = 16
screen_redraw_rate_per_second = 50
SingleColor_foreground = #009900FF
SingleColor_background = #111111FF
16Color_Palette = 0

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -25,6 +25,7 @@
MEM_START { MemoryAddresses.CMOS + 0x0000 }
MEM_SIZE { MemoryAddresses.CMOS + 0x0002 }
CLOCK_SPEED { MemoryAddresses.CMOS + 0x0004 }
SCREEN_REDRAW_RATE { MemoryAddresses.CMOS + 0x0006 }
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
DISK_LIST { MemoryAddresses.CMOS + 0x007E }
@ -108,7 +109,6 @@
@group Sig_VGA_Text_16_Color
CONTINUE 0x00
READ_VRAM 0x10
WRITE_VRAM 0x11
FORCE_REFRESH_SCREEN 0xE0

View file

@ -1,5 +1,7 @@
@guard _DISPLAY_INFO_DSS_
.code
_print_machine_info:
mov R9, $_bios_logo_2_line_1
mov R10, 0x0C

View file

@ -1,5 +1,7 @@
@guard _DRIVERS_DSS_
.code
## ============================= BIOS Interrupt handler =============================
_int_20_handler:
mov ACC, R10
@ -44,7 +46,6 @@ _int_20_end:
## ========================== BIOS Video Interrupt handler =========================
_int_30_handler:
## debug_profile_start 0xE0, DBGProfilerTime.MILLIS
mov ACC, R10
jeq $_int_30_direct_print_char_text_single, 0x0001
jeq $_int_30_direct_new_line_text_single, 0x0002
@ -59,7 +60,6 @@ _int_30_handler:
jeq $_int_30_invert_colors_text_single, 0x000B
jeq $_int_30_print_string_buffered, 0x000C
jeq $_int_30_read_vram_text16, 0x0020
jeq $_int_30_write_vram_text16, 0x0021
jeq $_int_30_clear_screen, 0x00E0
@ -139,13 +139,7 @@ _int_30_write_vram_text16:
inc R9
movb [VGA_Registers.MEMORY_CONTROLLER_Y_BYTE], *R9
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_16_Color.WRITE_VRAM
## debug_profile_stop
jmp $_int_30_end
_int_30_read_vram_text16:
jmp $_int_30_end
_int_30_clear_screen:
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.CLEAR_SCREEN

View file

@ -1,9 +1,14 @@
.load 0x0000 ## BIOS is mapped to address 0x0000 in memory
.entry _bios_entry_point
@include <data.dss>
@include <utils.dss>
@include <drivers.dss>
@include <display_info.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
@ -32,11 +37,4 @@
hlt ## Just in case somehow execution reaches this point
## ========================================================================
@include <drivers.dss>
@include <display_info.dss>
## This file contains the .data section, so it needs to be the last thing included
@include <utils.dss>
## ===============================================================================
.fixed 4096, 0xFF ## BIOS Needs to be 4096 Bytes exactly

View file

@ -1,6 +1,6 @@
@guard _UTILS_DSS_
@include <data.dss>
.code
_load_mbr_data_block:
movb [{MemoryAddresses.DISK_INTERFACE + 0x1}], 0x00 ## Mode = Read

View file

@ -68,7 +68,6 @@
## 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
READ_VRAM 0x10
WRITE_VRAM 0x11
FORCE_REFRESH_SCREEN 0xE0
FORCE_CLEAR_SCREEN 0xE1

View file

@ -1,6 +1,9 @@
.load 0x1740
.entry _drake_bootsector_entry_point
@include <../bios_api.dss>
@include <palette.dss>
@include <disk.dss>
.data
$string "Hello "
@ -9,64 +12,20 @@
$textCell <Text16VModeCell>
.code
_drake_bootsector_entry_point:
push 0
call $_load_dpt_block
movb [VGA_Registers.VIDEO_MODE], VGA_VideoModes.TEXT_16_COLORS
mov R5, 0
draw_loop:
push 2
push 1
push 2
call $_draw_palette
movb [$textCell.Character], 65
movb [$textCell.Foreground], 6
movb [$textCell.Background], 0
movb [$textCell.CoordX], R5
movb [$textCell.CoordY], 1
## mov R9, { $dpt_block + DPTStructure.ENTRIES_START + (2 * DPTStructure.ENTRY_SIZE_B) + DPTStructure.ENTRY_PART_LBL }
mov R10, 0x21
mov R9, $textCell
## debug_profile_start 0xE0, DBGProfilerTime.MILLIS
int 0x30
## debug_profile_stop
inc R5
mov ACC, R5
jgr $draw_loop, 90
mov R5, 0
draw_loop2:
movb [$textCell.Character], 65
movb [$textCell.Foreground], 6
movb [$textCell.Background], 0
movb [$textCell.CoordX], R5
movb [$textCell.CoordY], 10
mov R10, 0x21
mov R9, $textCell
int 0x30
inc R5
mov ACC, R5
jgr $draw_loop2, 90
mov R10, 0x0C
mov R9, $string
int 0x30
mov R10, 0x0C
mov R9, { $dpt_block + DPTStructure.ENTRIES_START + (2 * DPTStructure.ENTRY_SIZE_B) + DPTStructure.ENTRY_PART_LBL }
int 0x30
debug_break
end_loop:
jmp $end_loop
hlt
_load_dpt_block:
mov [$ddd.Mode], DiskMode.READ
mov [$ddd.Disk], 0x00
@ -80,7 +39,6 @@ _load_dpt_block:
ret
@include <disk.dss>
.fixed 5120, 0xFF

View file

@ -1,22 +1,25 @@
.load 0x1380
.entry _drake_loader_entry_point
@include <../bios_api.dss>
@include <disk.dss>
.data
$_drake_logo_line_1 " ___ ___ ___ __ ______"
$_drake_logo_line_2 " / _ \/ _ \/ _ | / //_/ __/"
$_drake_logo_line_3 " / // / , _/ __ |/ ,< / _/ "
$_drake_logo_line_4 "/____/_/|_/_/ |_/_/|_/___/ "
$_logo_padding " "
## $_drake_logo_line_1 " ___ ___ ___ __ ______"
## $_drake_logo_line_2 " / _ \/ _ \/ _ | / //_/ __/"
## $_drake_logo_line_3 " / // / , _/ __ |/ ,< / _/ "
## $_drake_logo_line_4 "/____/_/|_/_/ |_/_/|_/___/ "
## $_logo_padding " "
$ddd <DiskDriverData>
.code
mov R10, 0xE0
int 0x30
push 0
call $_print_logo
_drake_loader_entry_point:
## mov R10, 0xE0
## int 0x30
## push 0
## call $_print_logo
mov [$ddd.Mode], DiskMode.READ
mov [$ddd.Disk], 0x00
@ -30,28 +33,23 @@
call $_disk_load_from_ddd_blocking
jmp MemoryAddresses.RAM
_infinite_loop:
jmp $_infinite_loop
hlt
_print_logo:
mov R5, $_drake_logo_line_1
mov R6, 0
mov ACC, 6
_print_logo_loop:
mov R10, 0x0C
inc R6
mov R9, $_logo_padding
int 0x30
mov R9, R5
int 0x30
mov R10, 0x02
int 0x30
addip R5, 29
jls $_print_logo_loop, R6
ret
@include <disk.dss>
## _print_logo:
## mov R5, $_drake_logo_line_1
## mov R6, 0
## mov ACC, 6
## _print_logo_loop:
## mov R10, 0x0C
## inc R6
## mov R9, $_logo_padding
## int 0x30
## mov R9, R5
## int 0x30
## mov R10, 0x02
## int 0x30
## addip R5, 29
## jls $_print_logo_loop, R6
## ret
.fixed 512, 0x00

View file

@ -0,0 +1,46 @@
@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
debug_break
jge $_draw_palette_loop, 15
ret

View file

@ -1,751 +0,0 @@
.load 0x1740
@define EXT_MOV 0xE0
## @define wimm_in_dreg_immoffw 0x10
## @define wimm_in_dreg_regoff 0x11
## @define wimm_in_dreg_immoffb 0x12
@define bimm_in_dreg_immoffw 0x13
@define bimm_in_dreg_regoff 0x14
@define bimm_in_dreg_immoffb 0x15
## @define wdreg_in_dreg_immoffw 0x16
## @define wdreg_in_dreg_regoff 0x17
## @define wdreg_in_dreg_immoffb 0x18
@define bdreg_in_dreg_immoffw 0x19
@define bdreg_in_dreg_regoff 0x1A
@define bdreg_in_dreg_immoffb 0x1B
@define wimm_in_mem_immoffw 0x30
@define wimm_in_mem_regoff 0x31
@define wimm_in_mem_immoffb 0x32
@define bimm_in_mem_immoffw 0x33
@define bimm_in_mem_regoff 0x34
@define bimm_in_mem_immoffb 0x35
@define wdreg_immoffw_in_dreg 0x40
@define wdreg_regoff_in_dreg 0x41
@define wdreg_immoffb_in_dreg 0x42
@define bdreg_immoffw_in_dreg 0x43
@define bdreg_regoff_in_dreg 0x44
@define bdreg_immoffb_in_dreg 0x45
@define wmem_immoffw_in_reg 0x50
@define wmem_regoff_in_reg 0x51
@define wmem_immoffb_in_reg 0x52
@define bmem_immoffw_in_reg 0x53
@define bmem_regoff_in_reg 0x54
@define bmem_immoffb_in_reg 0x55
@define wdreg_immoffw_in_reg 0x56
@define wdreg_regoff_in_reg 0x57
@define wdreg_immoffb_in_reg 0x58
@define bdreg_immoffw_in_reg 0x59
@define bdreg_regoff_in_reg 0x5A
@define bdreg_immoffb_in_reg 0x5B
@define _IP 0x00
@define _SP 0x01
@define _FP 0x02
@define _RV 0x03
@define _PP 0x04
@define _FL 0x05
@define _ACC 0x06
@define _S1 0x07
@define _S2 0x08
@define _S3 0x09
@define _R1 0x0A
@define _R2 0x0B
@define _R3 0x0C
@define _R4 0x0D
@define _R5 0x0E
@define _R6 0x0F
@define _R7 0x10
@define _R8 0x11
@define _R9 0x12
@define _R10 0x13
.code
mov R5, 0x00 ## R5 is the test counter
mov R6, 0x00 ## R6 is used as flag set if one test fails
mov R10, 0xE0 ## Clear the screen
int 0x30 ## --
## debug_break
## ------ Test 1 ------
debug_break
inc R5
mov R1, 0x3000
inc R8
omov *R1, 0xFAAA, word 0x02
## %low EXT_MOV wimm_in_dreg_immoffw _R1 0xFA 0xAA 0x00 0x02
add R1, 0x02
mov R1, ACC
mov ACC, *R1
jeq $test_1_passed, 0xFAAA
push 0
call $test_failed
inc R6
test_1_passed:
## ------ Test 2 ------
## debug_break
inc R5
mov R1, 0x3000
mov R2, 0x03
omov *R1, 0xFAAA, R2
## %low EXT_MOV wimm_in_dreg_regoff _R1 0xFA 0xAA _R2
add R1, 0x03
mov R1, ACC
mov ACC, *R1
jeq $test_2_passed, 0xFAAA
push 0
call $test_failed
inc R6
test_2_passed:
## ------ Test 3 ------
## debug_break
inc R5
mov R1, 0x3000
omov *R1, 0xFAAA, 0x04
## %low EXT_MOV wimm_in_dreg_immoffb _R1 0xFA 0xAA 0x04
add R1, 0x04
mov R1, ACC
mov ACC, *R1
jeq $test_3_passed, 0xFAAA
push 0
call $test_failed
inc R6
test_3_passed:
## ------ Test 4 ------
## debug_break
inc R5
mov R1, 0x3000
omovb *R1, 0xEE, word 0x06
## %low EXT_MOV bimm_in_dreg_immoffw _R1 0xEE 0x00 0x06
add R1, 0x06
mov R1, ACC
movb ACC, *R1
jeq $test_4_passed, 0xEE
push 0
call $test_failed
inc R6
test_4_passed:
## ------ Test 5 ------
## debug_break
inc R5
mov R1, 0x3000
mov R2, 0x06
omovb *R1, 0x11, R2
## %low EXT_MOV bimm_in_dreg_regoff _R1 0x11 _R2
add R1, 0x06
mov R1, ACC
movb ACC, *R1
jeq $test_5_passed, 0x11
push 0
call $test_failed
inc R6
test_5_passed:
## ------ Test 6 ------
## debug_break
inc R5
mov R1, 0x3000
omovb *R1, 0x22, 0x08
## %low EXT_MOV bimm_in_dreg_immoffb _R1 0x22 0x08
add R1, 0x08
mov R1, ACC
movb ACC, *R1
jeq $test_6_passed, 0x22
push 0
call $test_failed
inc R6
test_6_passed:
## ------ Test 7 ------
## debug_break
inc R5
mov R1, 0x5000
mov R3, 0x4000
mov *R3, 0x33
omov *R1, *R3, word 0x0A
## %low EXT_MOV wdreg_in_dreg_immoffw _R1 _R3 0x00 0x0A
add R1, 0x0A
mov R1, ACC
mov ACC, *R1
jeq $test_7_passed, 0x33
push 0
call $test_failed
inc R6
test_7_passed:
## ------ Test 8 ------
## debug_break
inc R5
mov R1, 0x5000
mov R3, 0x4000
mov *R3, 0x44
mov R2, 0x0C
omov *R1, *R3, R2
## %low EXT_MOV wdreg_in_dreg_regoff _R1 _R3 _R2
add R1, 0x0C
mov R1, ACC
mov ACC, *R1
jeq $test_8_passed, 0x44
push 0
call $test_failed
inc R6
test_8_passed:
## ------ Test 9 ------
## debug_break
inc R5
mov R1, 0x5000
mov R3, 0x4000
mov *R3, 0x55
omov *R1, *R3, 0x0E
## %low EXT_MOV wdreg_in_dreg_immoffb _R1 _R3 0x0E
add R1, 0x0E
mov R1, ACC
mov ACC, *R1
jeq $test_9_passed, 0x55
push 0
call $test_failed
inc R6
test_9_passed:
## ------ Test 10 ------
## debug_break
inc R5
mov R1, 0x6000
mov R3, 0x5000
movb *R3, 0x66
omovb *R1, *R3, word 0x10
## %low EXT_MOV bdreg_in_dreg_immoffw _R1 _R3 0x00 0x10
add R1, 0x10
mov R1, ACC
movb ACC, *R1
jeq $test_10_passed, 0x66
push 0
call $test_failed
inc R6
test_10_passed:
## ------ Test 11 ------
## debug_break
inc R5
mov R1, 0x6000
mov R3, 0x5000
movb *R3, 0x77
mov R2, 0x12
omovb *R1, *R3, R2
## %low EXT_MOV bdreg_in_dreg_regoff _R1 _R3 _R2
add R1, 0x12
mov R1, ACC
movb ACC, *R1
jeq $test_11_passed, 0x77
push 0
call $test_failed
inc R6
test_11_passed:
## ------ Test 12 ------
## debug_break
inc R5
mov R1, 0x6000
mov R3, 0x5000
movb *R3, 0x88
omovb *R1, *R3, 0x14
## %low EXT_MOV bdreg_in_dreg_immoffb _R1 _R3 0x14
add R1, 0x14
mov R1, ACC
movb ACC, *R1
jeq $test_12_passed, 0x88
push 0
call $test_failed
inc R6
test_12_passed:
## ------ Test 13 ------
## debug_break
inc R5
omov [0x7000], 0xAA99, word 0x16
## %low EXT_MOV wimm_in_mem_immoffw 0x70 0x00 0xAA 0x99 0x00 0x16
mov R1, 0x7000
add R1, 0x16
mov R1, ACC
mov ACC, *R1
jeq $test_13_passed, 0xAA99
push 0
call $test_failed
inc R6
test_13_passed:
## ------ Test 14 ------
## debug_break
inc R5
mov R2, 0x18
omov [0x7000], 0xAAAA, R2
## %low EXT_MOV wimm_in_mem_regoff 0x70 0x00 0xAA 0xAA _R2
mov R1, 0x7000
add R1, 0x18
mov R1, ACC
mov ACC, *R1
jeq $test_14_passed, 0xAAAA
push 0
call $test_failed
inc R6
test_14_passed:
## ------ Test 15 ------
## debug_break
inc R5
omov [0x7000], 0xAABB, 0x1A
## %low EXT_MOV wimm_in_mem_immoffb 0x70 0x00 0xAA 0xBB 0x1A
mov R1, 0x7000
add R1, 0x1A
mov R1, ACC
mov ACC, *R1
jeq $test_15_passed, 0xAABB
push 0
call $test_failed
inc R6
test_15_passed:
## ------ Test 16 ------
## debug_break
inc R5
omovb [0x8000], 0xCC, word 0x1C
## %low EXT_MOV bimm_in_mem_immoffw 0x80 0x00 0xCC 0x00 0x1C
mov R1, 0x8000
add R1, 0x1C
mov R1, ACC
movb ACC, *R1
jeq $test_16_passed, 0xCC
push 0
call $test_failed
inc R6
test_16_passed:
## ------ Test 17 ------
## debug_break
inc R5
mov R2, 0x1E
omovb [0x8000], 0xDD, R2
## %low EXT_MOV bimm_in_mem_regoff 0x80 0x00 0xDD _R2
mov R1, 0x8000
add R1, 0x1E
mov R1, ACC
movb ACC, *R1
jeq $test_17_passed, 0xDD
push 0
call $test_failed
inc R6
test_17_passed:
## ------ Test 18 ------
## debug_break
inc R5
omovb [0x8000], 0xEE, 0x20
## %low EXT_MOV bimm_in_mem_immoffb 0x80 0x00 0xEE 0x20
mov R1, 0x8000
add R1, 0x20
mov R1, ACC
movb ACC, *R1
jeq $test_18_passed, 0xEE
push 0
call $test_failed
inc R6
test_18_passed:
## ------ Test 19 ------
## debug_break
inc R5
mov R1, 0x9000
mov R3, 0xA000
mov [0xA022], 0x66
movo *R1, *R3, word 0x22
## %low EXT_MOV wdreg_immoffw_in_dreg _R1 _R3 0x00 0x22
mov ACC, *R1
jeq $test_19_passed, 0x66
push 0
call $test_failed
inc R6
test_19_passed:
## ------ Test 20 ------
## debug_break
inc R5
mov R1, 0x9000
mov R3, 0xA000
mov [0xA033], 0x77
mov R2, 0x33
movo *R1, *R3, R2
## %low EXT_MOV wdreg_regoff_in_dreg _R1 _R3 _R2
mov ACC, *R1
jeq $test_20_passed, 0x77
push 0
call $test_failed
inc R6
test_20_passed:
## ------ Test 21 ------
## debug_break
inc R5
mov R1, 0x9000
mov R3, 0xA000
mov [0xA044], 0x88
movo *R1, *R3, 0x44
## %low EXT_MOV wdreg_immoffb_in_dreg _R1 _R3 0x44
mov ACC, *R1
jeq $test_21_passed, 0x88
push 0
call $test_failed
inc R6
test_21_passed:
## ------ Test 22 ------
## debug_break
inc R5
mov R1, 0xA000
mov R3, 0xB000
movb [0xB055], 0x99
movbo *R1, *R3, word 0x55
## %low EXT_MOV bdreg_immoffw_in_dreg _R1 _R3 0x00 0x55
movb ACC, *R1
jeq $test_22_passed, 0x99
push 0
call $test_failed
inc R6
test_22_passed:
## ------ Test 23 ------
## debug_break
inc R5
mov R1, 0xA000
mov R3, 0xB000
movb [0xB066], 0xAA
mov R2, 0x66
movbo *R1, *R3, R2
## %low EXT_MOV bdreg_regoff_in_dreg _R1 _R3 _R2
movb ACC, *R1
jeq $test_23_passed, 0xAA
push 0
call $test_failed
inc R6
test_23_passed:
## ------ Test 24 ------
## debug_break
inc R5
mov R1, 0xA000
mov R3, 0xB000
movb [0xB077], 0xBB
movbo *R1, *R3, 0x77
## %low EXT_MOV bdreg_immoffb_in_dreg _R1 _R3 0x77
movb ACC, *R1
jeq $test_24_passed, 0xBB
push 0
call $test_failed
inc R6
test_24_passed:
## ------ Test 25 ------
## debug_break
inc R5
mov [0xC088], 0xCC
movo R1, [0xC000], word 0x88
## %low EXT_MOV wmem_immoffw_in_reg _R1 0xC0 0x00 0x00 0x88
mov ACC, R1
jeq $test_25_passed, 0xCC
push 0
call $test_failed
inc R6
test_25_passed:
## ------ Test 26 ------
## debug_break
inc R5
mov [0xC099], 0xDD
mov R2, 0x99
movo R1, [0xC000], R2
## %low EXT_MOV wmem_regoff_in_reg _R1 0xC0 0x00 _R2
mov ACC, R1
jeq $test_26_passed, 0xDD
push 0
call $test_failed
inc R6
test_26_passed:
## ------ Test 27 ------
## debug_break
inc R5
mov [0xC0AA], 0xEE
movo R1, [0xC000], 0xAA
## %low EXT_MOV wmem_immoffb_in_reg _R1 0xC0 0x00 0xAA
mov ACC, R1
jeq $test_27_passed, 0xEE
push 0
call $test_failed
inc R6
test_27_passed:
## ------ Test 28 ------
## debug_break
inc R5
movb [0xD099], 0x11
movbo R1, [0xD000], word 0x99
## %low EXT_MOV bmem_immoffw_in_reg _R1 0xD0 0x00 0x00 0x99
mov ACC, R1
jeq $test_28_passed, 0x11
push 0
call $test_failed
inc R6
test_28_passed:
## ------ Test 29 ------
## debug_break
inc R5
movb [0xD0AA], 0x22
mov R2, 0xAA
movbo R1, [0xD000], R2
## %low EXT_MOV bmem_regoff_in_reg _R1 0xD0 0x00 _R2
mov ACC, R1
jeq $test_29_passed, 0x22
push 0
call $test_failed
inc R6
test_29_passed:
## ------ Test 30 ------
## debug_break
inc R5
movb [0xD0BB], 0x33
movbo R1, [0xD000], 0xBB
## %low EXT_MOV bmem_immoffb_in_reg _R1 0xD0 0x00 0xBB
mov ACC, R1
jeq $test_30_passed, 0x33
push 0
call $test_failed
inc R6
test_30_passed:
## ------ Test 31 ------
## debug_break
inc R5
mov R3, 0x4000
mov [0x40CC], 0x44
movo R1, *R3, word 0xCC
## %low EXT_MOV wdreg_immoffw_in_reg _R1 _R3 0x00 0xCC
mov ACC, R1
jeq $test_31_passed, 0x44
push 0
call $test_failed
inc R6
test_31_passed:
## ------ Test 32 ------
## debug_break
inc R5
mov R3, 0x4000
mov [0x40DD], 0x55
mov R2, 0xDD
movo R1, *R3, R2
## %low EXT_MOV wdreg_regoff_in_reg _R1 _R3 _R2
mov ACC, R1
jeq $test_32_passed, 0x55
push 0
call $test_failed
inc R6
test_32_passed:
## ------ Test 33 ------
## debug_break
inc R5
mov R3, 0x4000
mov [0x40EE], 0x66
movo R1, *R3, 0xEE
## %low EXT_MOV wdreg_immoffb_in_reg _R1 _R3 0xEE
mov ACC, R1
jeq $test_33_passed, 0x66
push 0
call $test_failed
inc R6
test_33_passed:
## ------ Test 34 ------
## debug_break
inc R5
mov R3, 0x5000
movb [0x5011], 0x77
movbo R1, *R3, word 0x11
## %low EXT_MOV bdreg_immoffw_in_reg _R1 _R3 0x00 0x11
mov ACC, R1
jeq $test_34_passed, 0x77
push 0
call $test_failed
inc R6
test_34_passed:
## ------ Test 35 ------
## debug_break
inc R5
mov R3, 0x5000
movb [0x5022], 0x88
mov R2, 0x22
movbo R1, *R3, R2
## %low EXT_MOV bdreg_regoff_in_reg _R1 _R3 _R2
mov ACC, R1
jeq $test_35_passed, 0x88
push 0
call $test_failed
inc R6
test_35_passed:
## ------ Test 36 ------
## debug_break
inc R5
mov R3, 0x5000
movb [0x5033], 0x99
movbo R1, *R3, 0x33
## %low EXT_MOV bdreg_immoffb_in_reg _R1 _R3 0x33
mov ACC, R1
jeq $test_36_passed, 0x99
push 0
call $test_failed
inc R6
test_36_passed:
## ------- END -------
debug_break
movb ACC, [$test_count]
sub ACC, R6
mov R6, ACC
mov R10, 0x03
mov R9, $tests_pass_str
int 0x30
mov R10, 0x01
mov R9, 32
int 0x30
mov R10, 0x04
mov R9, R6
int 0x30
mov R10, 0x01
mov R9, 47
int 0x30
mov R10, 0x04
movb R9, [$test_count]
int 0x30
mov R10, 0x02
int 0x30
end:
jmp $end
hlt
test_failed:
mov R10, 0x03
mov R9, $test_fail_str
int 0x30
mov R10, 0x01
mov R9, 32
int 0x30
mov R10, 0x04
mov R9, R5
int 0x30
mov R10, 0x02
int 0x30
ret
.data
$test_fail_str "FAIL: Test"
$tests_pass_str "Tests passed:"
$test_count 36

View file

@ -1,105 +0,0 @@
##=================================================================================================================================
## 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 R10, 0x00
mov R9, $_text_entered_handler
mov R8, 0xA2
int 0x20 ## Enable text entered handler
mov R10, 0x00
mov R9, $_key_pressed_handler
mov R8, 0xA0
int 0x20 ## Enable key pressed handler
mov R10, 0x0B
int 0x30 ## Invert colors
mov R10, 0x01
mov R9, 62
int 0x30 ## Print first prompt char
mov R10, 0x0B
int 0x30 ## Invert colors
mov R10, 0x01
mov R9, 32
int 0x30 ## Print space
mov R1, 0 ## Zero the counter
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
_text_entered_handler:
mov R9, [0x1282]
mov R10, 0x01
int 0x30
rti
_key_pressed_handler:
mov ACC, [0x1282]
jeq $_key_pressed_handler_backspace, 8
jne $_key_pressed_handler_end, 13
mov R10, 0x02
int 0x30
mov R10, 0x0B
int 0x30 ## Invert colors
mov R10, 0x01
mov R9, 62
int 0x30
mov R10, 0x0B
int 0x30 ## Invert colors
mov R10, 0x01
mov R9, 32
int 0x30
jmp $_key_pressed_handler_end
_key_pressed_handler_backspace:
debug_break
mov R9, ACC
mov R10, 0x01
int 0x30
_key_pressed_handler_end:
rti
.fixed 512, 0x00

View file

@ -1,101 +0,0 @@
##=================================================================================================================================
## 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
## 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
## results can be seen, since there is no Virtual Display implemented yet in the Dragon Runtime (that's the next thing to come).
##=================================================================================================================================
.load 0x1740 ## The program is loaded at address 0x1740, which is the first address of normal RAM
##=================================================================================================================================
## This is the data section, used to declare variables that will be stored inside the application space
##=================================================================================================================================
.data
$hello_world_str "Hello World!!" ## In the data section only, you can declare a stream of bytes as a
## string literal between double-quotes. The assembler will convert
## it into the corresponding bytes, and will add a 0 byte at the end
## as the null termination.
$n1 0x00, 0x00 ## Other data declared in the data section must be represented as a
$n2 0x00, 0x01 ## comma-separated series of bytes (except for string literals - see
$n3 0x00, 0x01 ## above). No size data is stored for byte streams.
##=================================================================================================================================
##=================================================================================================================================
## This is the start of the .code section, and it acts as the entry point for the program
##=================================================================================================================================
.code
push $hello_world_str ## Push the address of the first character of the $hello_world_str string to the stack
push 1 ## Push the number 1 to the stack, as the number of arguments for the next call instruction
call $strlen ## Call the $strlen subroutine
mov R1, RV ## Load the return value into the R1 register
debug_break ## This debug break is here for the debugger to pause, in order to see the results of
## the function call in the debugger, since the Virtual Display is not implemented yet.
push 25 ## Push the number 25 as a parameter to the $fibonacci subroutine, so that it will
## calculate up to the 25th fibonacci value, which is the maximum for 16-bits.
push 1 ## Push the number 1 to the stack, as the number of arguments for the next call instruction
call $fibonacci ## Call the $fibonacci subroutine
mov R2, RV ## Load the return value into the R2 register
debug_break ## This debug break is here for the debugger to pause, in order to see the results of
## the function call in the debugger, since the Virtual Display is not implemented yet.
hlt ## This is the halt instruction, and it stops the CPU of the Virtual Machine.
##=================================================================================================================================
##=================================================================================================================================
## Subroutine to calculate the length of a null-terminated string
## It expects the address of the first character of the
## string, pushed onto the stack
##=================================================================================================================================
strlen:
arg R1 ## Store the first argument (address of the string) into the R1 register
mov R2, 0 ## Zero the R2 register, which will be used to store the length of the string
_strlen_loop:
movb ACC, *R1 ## Dereference the R1 register (pointer to the string), to get the first character of the string
inc R1 ## Increment the R1 register (pointer to the string) so that it points to the next byte
jeq $_streln_loop_end, 0 ## If the character ascii value is 0, we are done counting and we jump to the $_streln_loop_end label
inc R2 ## Else, increment the R2 register, because the character is not a zero so we add 1 to the count
jmp $_strlen_loop ## Jump to the $_strlen_loop label (beginning of the loop)
_streln_loop_end:
mov RV, R2 ## Copy the value of the R2 register (length of the string) to the RV register (Return Value)
ret ## Return to the calling code
##=================================================================================================================================
##=================================================================================================================================
## Subroutine to calculate the fibonacci sequence
## It expects Nth number (starting at 1) up to which
## to calculate, pushed onto the stack
##=================================================================================================================================
fibonacci:
mov R1, 0 ## R1, R2, R3 Registers will be used as variables for the calculation
mov R2, 1 ## --
mov R3, 1 ## --
arg R4 ## Store the first argument (Nth number of the fibonacci sequence) into the R4 register
mov ACC, 3 ## --
jle $_fibonacci_loop_end, R4 ## Compare the value passed as parameter and if less or equals to 3 (ACC Register) jump to the end
dec R4 ## Decrement the R4 register by 1, to convert from index-1 to index-0
mov R5, 2 ## Load the numebr 2 into the R5 register, this will be used as the loop counter
_fibonacci_loop:
add R1, R2 ## Add R1 and R2 registers
mov R3, ACC ## andstore the result into the R3 register
##debug_break ## This commented debug_break can be uncommented in order to analyze every iteration of the loop in the debugger
mov R1, R2 ## Swap the numbers around
mov R2, R3 ## --
mov ACC, R5 ## Load the value of the R5 register (used as the loop counter) into the ACC register
jeq $_fibonacci_loop_end, R4 ## If the counter is equals to the R4 register (parameter passed from calling code) jump to the end of the loop
inc R5 ## else increment the counter
jmp $_fibonacci_loop ## and jump to the beginning of the loop
_fibonacci_loop_end:
mov Rv, R3 ## Load the final result (stored in the R3 register) into the RV (Return Value) register
ret ## Return to the calling code
##=================================================================================================================================
.fixed 512, 0x00 ## This directive is used to fill (with 0x00 bytes) the binary output file from the assembler,
## exactly to 512 bytes.

View file

@ -1,48 +0,0 @@
##=================================================================================================================================
## 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

View file

@ -8,6 +8,7 @@
MemStart: (2 bytes) 0x0000
MemSize: (2 bytes) 0x0002
ClockSpeed: (2 bytes) 0x0004
DisplayRedrawRate: (1 bytes) 0x0006
BootDisk: 0x0010
DiskList: (2 bytes) 0x007E
@ -92,7 +93,6 @@
0x06: Text Single Color - Print Buffer Without Flushing
0x07: Text Single Color - Print Buffered String
0x10: Text 16 Colors - Read Memory
0x11: Text 16 Colors - Write Memory
0xE0: Refresh Screen
@ -143,7 +143,7 @@
0x0B: Toggles inverted colors in Text Single Mode
0x20: Read VRAM in Text16 Colors Mode (Cell address stored in R9)
0x20: Write VRAM in Text16 Colors Mode (Cell address stored in R9)
0x21: Write VRAM in Text16 Colors Mode (Cell address stored in R9)
0xE0: Refresh Screen
0xE1: Clear Screen

View file

@ -2,7 +2,6 @@ Assembler:
Add subroutine address export functionality
Bugs:
Fix VM closing when reaching hlt instruction
Refactor:
Move all possible default values into data::DefaultValues class (in <GlobalData.hpp>)
@ -13,6 +12,7 @@ External:
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

View file

@ -750,6 +750,7 @@ namespace dragon
for (auto& line : m_lines)
{
ostd::String lineEdit(line);
lineEdit.trim();
if (lineEdit.startsWith(".data"))
currentSection = DATA_SECTION;
else if (lineEdit.startsWith(".code"))
@ -790,6 +791,18 @@ namespace dragon
m_fixedSize = fixedSizeEdit.toInt();
continue;
}
else if (lineEdit.startsWith(".entry "))
{
if (lineEdit.len() < 8)
{
//TODO: Error
std::cout << "Invalid .entry value: " << lineEdit << "\n";
return;
}
lineEdit.substr(7).trim();
m_entry_lbl = lineEdit;
continue;
}
else if (lineEdit.startsWith(".load "))
{
if (lineEdit.len() < 7)
@ -2319,6 +2332,17 @@ namespace dragon
void Assembler::combineDataAndCode(void)
{
uint16_t entryAddr = m_dataSize + m_loadAddress + 3;
if (m_entry_lbl != "")
{
if (m_labelTable.count("$" + m_entry_lbl) == 0)
{
std::cout << "Invalid entry label: " << m_entry_lbl << ".\n";
exit(0);
return;
}
auto lbl = m_labelTable["$" + m_entry_lbl];
entryAddr = lbl.address;
}
std::vector<tSymbol> symbols;
ostd::ByteStream newCode;
newCode.push_back(data::OpCodes::Jmp);

View file

@ -162,6 +162,7 @@ namespace dragon
inline static uint16_t m_currentDataAddr { 0x0000 };
inline static uint16_t m_dataSize { 0x0000 };
inline static uint16_t m_programSize { 0x0000 };
inline static ostd::String m_entry_lbl { "" };
inline static std::vector<tStructDefinition> m_structDefs;
inline static std::vector<tDisassemblyLine> m_disassembly;

View file

@ -199,7 +199,7 @@ namespace dragon
bool VirtualCPU::execute(void)
{
if (m_halt) return false;
if (m_halt) return true;
m_currentExtension = nullptr;
m_currentExtInst = 0x00;
m_isDebugBreakPoint = false;
@ -765,7 +765,7 @@ namespace dragon
case data::OpCodes::Halt:
{
m_halt = true;
return false;
return true;
}
break;
case data::OpCodes::PushImm:

View file

@ -66,7 +66,6 @@ namespace dragon
auto xy = CONVERT_1D_2D(i, RawTextRenderer::CONSOLE_CHARS_H);
RawTextRenderer::drawString(ostd::String().addChar(character), xy.x, xy.y, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, foreground, background);
}
DragonRuntime::cpu.handleInterrupt(data::InterruptCodes::Text16ModeScreenRefreshed, true);
m_refreshScreen = false;
}
}
@ -74,6 +73,7 @@ namespace dragon
if (m_redrawScreen)
{
m_renderer.updateBuffer();
DragonRuntime::cpu.handleInterrupt(data::InterruptCodes::Text16ModeScreenRefreshed, true);
m_redrawScreen = false;
}
m_renderer.displayBuffer();
@ -136,11 +136,7 @@ namespace dragon
}
else if (video_mode == tVideoModeValues::Text16Colors)
{
if (signal == tSignalValues::Text16Color_ReadMemory)
{
}
else if (signal == tSignalValues::Text16Color_WriteMemory)
if (signal == tSignalValues::Text16Color_WriteMemory)
{
hw::interface::Graphics::tText16_Cell textCell;

View file

@ -43,7 +43,6 @@ namespace dragon
inline static constexpr uint8_t TextSingleColor_DirectPrintBuffNoFlush = 0x06;
inline static constexpr uint8_t TextSingleColor_DirectPrintString = 0x07;
inline static constexpr uint8_t Text16Color_ReadMemory = 0x10;
inline static constexpr uint8_t Text16Color_WriteMemory = 0x11;
inline static constexpr uint8_t RefreshScreen = 0xE0;

View file

@ -109,6 +109,13 @@ namespace dragon
if (!lineEdit.isNumeric()) continue; //TODO: Error
config.text16_palette = lineEdit.toInt();
}
else if (lineEdit == "screen_redraw_rate_per_second")
{
lineEdit = tokens.next();
lineEdit.trim().toLower();
if (!lineEdit.isNumeric()) continue; //TODO: Error
config.screen_redraw_rate_per_second = lineEdit.toInt();
}
else continue; //TODO: Warning
}
return validate_machine_config(config);

View file

@ -18,6 +18,7 @@ namespace dragon
ostd::Color singleColor_background;
ostd::Color singleColor_foreground;
uint8_t text16_palette { 0 };
uint8_t screen_redraw_rate_per_second { 10 };
inline bool isValid(void) const { return m_valid; }
inline void destroy(void) { for (auto& ptr : cpuext_list) delete ptr.second; }

View file

@ -313,11 +313,13 @@ namespace dragon
out.fg(ostd::ConsoleColors::BrightYellow).p(" Fixed clock enabled: ").p(STR_BOOL(machine_config.fixed_clock)).nl();
if (machine_config.fixed_clock)
out.fg(ostd::ConsoleColors::BrightYellow).p(" Clock speed: ").p(machine_config.clock_rate_sec).p(" Hz").nl();
out.fg(ostd::ConsoleColors::BrightYellow).p(" Screen redraw rate: ").p((int32_t)machine_config.screen_redraw_rate_per_second).p(" Hz").nl();
}
vCMOS.write16(data::CMOSRegisters::MemoryStart, data::MemoryMapAddresses::Memory_Start);
vCMOS.write16(data::CMOSRegisters::MemorySize, data::MemoryMapAddresses::Memory_End);
vCMOS.write16(data::CMOSRegisters::ClockSpeed, machine_config.clock_rate_sec);
vCMOS.write8 (data::CMOSRegisters::ScreenRedrawRate, machine_config.screen_redraw_rate_per_second);
ostd::BitField_16 disk_list_bitfield;
disk_list_bitfield.value = 0;
for (int32_t i = 0; i < 16; i++)
@ -360,6 +362,7 @@ namespace dragon
ostd::SignalHandler::refresh();
uint16_t addr = cpu.readRegister(dragon::data::Registers::IP);
uint16_t spAddr = cpu.readRegister(dragon::data::Registers::SP);
uint8_t screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate);
// _timer.start(true, "Profiling", ostd::eTimeUnits::Microseconds, &out);
running = cpu.execute() && vDisplay.isRunning();
// _timer.end(true);
@ -378,7 +381,7 @@ namespace dragon
// out.fg(ostd::ConsoleColors::Red).p(s_avgInstTime).nl().reset();
acc = 0;
}
if (acc2 == 100)
if (acc2 == (1000 / screenRedrawRate))
{
vDisplay.redrawScreen();
acc2 = 0;
@ -398,6 +401,7 @@ namespace dragon
__track_call_stack(&s_machineInfo);
bool running = cpu.execute() && vDisplay.isRunning();
vDisplay.update();
vDisplay.redrawScreen(); // This is slow...maybe it should be on a 100ms rate, like in normal runtime mode
vDiskInterface.cycleStep();
__get_machine_footprint(&s_machineInfo, trackedAddresses, false);
return running || vDiskInterface.isBusy();

View file

@ -126,22 +126,22 @@ namespace dragon
public:
inline BiosVideoDefaultPalette(void)
{
m_colors.push_back({ 0, 0, 0 });
m_colors.push_back({ 157, 157, 157 });
m_colors.push_back({ 255, 255, 255 });
m_colors.push_back({ 190, 38, 51 });
m_colors.push_back({ 224, 111, 139 });
m_colors.push_back({ 73, 60, 43 });
m_colors.push_back({ 164, 100, 34 });
m_colors.push_back({ 235, 137, 49 });
m_colors.push_back({ 247, 226, 107 });
m_colors.push_back({ 47, 80, 42 });
m_colors.push_back({ 68, 137, 26 });
m_colors.push_back({ 163, 206, 39 });
m_colors.push_back({ 27, 38, 50 });
m_colors.push_back({ 0, 87, 132 });
m_colors.push_back({ 49, 162, 242 });
m_colors.push_back({ 178, 220, 239 });
m_colors.push_back({ 0, 0, 0 }); // Black
m_colors.push_back({ 157, 157, 157 }); // Gray
m_colors.push_back({ 255, 255, 255 }); // White
m_colors.push_back({ 190, 38, 51 }); // Red
m_colors.push_back({ 224, 111, 139 }); // Pink
m_colors.push_back({ 73, 60, 43 }); // Brown
m_colors.push_back({ 164, 100, 34 }); // Dark Orange
m_colors.push_back({ 235, 137, 49 }); // Orange
m_colors.push_back({ 247, 226, 107 }); // Yellow
m_colors.push_back({ 47, 80, 42 }); // Dark Green
m_colors.push_back({ 68, 137, 26 }); // Green
m_colors.push_back({ 163, 206, 39 }); // Lime
m_colors.push_back({ 27, 38, 50 }); // Dark Blue
m_colors.push_back({ 0, 87, 132 }); // Blue
m_colors.push_back({ 49, 162, 242 }); // Light Blue
m_colors.push_back({ 178, 220, 239 }); // Sky
}
inline ostd::Color getColor(uint8_t col) override
@ -219,6 +219,7 @@ namespace dragon
inline static constexpr uint8_t MemoryStart = 0x00;
inline static constexpr uint8_t MemorySize = 0x02;
inline static constexpr uint8_t ClockSpeed = 0x04;
inline static constexpr uint8_t ScreenRedrawRate = 0x06;
inline static constexpr uint8_t BootDisk = 0x10;
inline static constexpr uint8_t DiskList = 0x7E;