]> git.the-white-hart.net Git - vhdl/commitdiff
Add IO test assembly program for CPU0
authorrs <>
Thu, 2 Oct 2025 00:06:37 +0000 (19:06 -0500)
committerrs <>
Thu, 2 Oct 2025 00:06:37 +0000 (19:06 -0500)
projects/cpu_0/asm/write.asm [new file with mode: 0644]

diff --git a/projects/cpu_0/asm/write.asm b/projects/cpu_0/asm/write.asm
new file mode 100644 (file)
index 0000000..3659917
--- /dev/null
@@ -0,0 +1,332 @@
+( VGA region bases )
+vga_scr=0x02000000
+vga_tile=0x02004000
+vga_pal=0x02006000
+
+( host registers )
+host_ctrl=0x02008000
+host_flags=0x02008001
+host_mbox=0x02008002
+host_swled=0x02008003
+host_sseg0=0x02008004
+host_sseg1=0x02008005
+host_sseg2=0x02008006
+host_sseg3=0x02008007
+
+( ps2 registers )
+ps2_ctrl=0x02008008
+ps2_imask=0x02008009
+ps2_iflag=0x0200800a
+ps2_error=0x0200800b
+ps2_data=0x0200800c
+
+( rs232 registers )
+uart_ctrl=0x02008010
+uart_baudl=0x02008011
+uart_baudh=0x02008012
+uart_imask=0x02008013
+uart_iflag=0x02008014
+uart_data=0x02008015
+
+( timer registers )
+timer0_ctrl=0x02008018
+timer0_count_l=0x02008019
+timer0_count_m=0x0200801a
+timer0_count_h=0x0200801b
+timer1_ctrl=0x0200801c
+timer1_count_l=0x0200801d
+timer1_count_m=0x0200801e
+timer1_count_h=0x0200801f
+
+
+( ---------------------------------------------------------------------------- )
+( Interrupt service routines )
+
+
+( ivec -- )
+isr:
+    dup #8 5i8 - jn isr_unk
+    dup + dup + #32 isr_jumptable + @32 >r ;
+
+    align
+isr_jumptable:
+    isr_reset
+    isr_flags
+    isr_ps2
+    isr_uart
+    isr_timer0
+    isr_timer1
+
+
+( reset )
+isr_reset:
+    ( Write palette to VGA controller )
+    #8 0x00i8 #32 vga_pal #8 0x00i8 + !8 drop
+    #8 0x60i8 #32 vga_pal #8 0x01i8 + !8 drop
+    #8 0x0ci8 #32 vga_pal #8 0x02i8 + !8 drop
+    #8 0x01i8 #32 vga_pal #8 0x03i8 + !8 drop
+    #8 0x6ci8 #32 vga_pal #8 0x04i8 + !8 drop
+    #8 0x0di8 #32 vga_pal #8 0x05i8 + !8 drop
+    #8 0x61i8 #32 vga_pal #8 0x06i8 + !8 drop
+    #8 0x6di8 #32 vga_pal #8 0x07i8 + !8 drop
+    #8 0x92i8 #32 vga_pal #8 0x08i8 + !8 drop
+    #8 0xe0i8 #32 vga_pal #8 0x09i8 + !8 drop
+    #8 0x1ci8 #32 vga_pal #8 0x0ai8 + !8 drop
+    #8 0x03i8 #32 vga_pal #8 0x0bi8 + !8 drop
+    #8 0xfci8 #32 vga_pal #8 0x0ci8 + !8 drop
+    #8 0x1fi8 #32 vga_pal #8 0x0di8 + !8 drop
+    #8 0xe3i8 #32 vga_pal #8 0x0ei8 + !8 drop
+    #8 0xffi8 #32 vga_pal #8 0x0fi8 + !8 drop
+
+    ( Clear LEDs )
+    #8 0x00i8 #32 host_swled !8 drop
+    #8 0xffi8 #32 host_sseg0 !8 drop
+    #8 0xffi8 #32 host_sseg1 !8 drop
+    #8 0xffi8 #32 host_sseg2 !8 drop
+    #8 0xffi8 #32 host_sseg3 !8 drop
+
+    ( Enable PS2 block and Rx interrupt )
+    ( #8 0x41i8 #32 ps2_ctrl  !8 drop
+    #8 0x01i8 #32 ps2_imask !8 drop )
+
+    ( 9600 baud, enable Tx/Rx )
+    #8 0x01i8 #32 uart_baudh !8 drop
+    #8 0x46i8 #32 uart_baudl !8 drop
+    ( #8 0x01i8 #32 uart_imask !8 drop )
+    #8 0x13i8 #32 uart_ctrl  !8 drop
+
+    ( Enable timer 0 with 1s period, auto-restart )
+    ( #8 0x02i8 #32 timer0_count_h !8 drop )
+    ( #8 0xfai8 #32 timer0_count_m !8 drop )
+    ( #8 0xf0i8 #32 timer0_count_l !8 drop )
+    ( #8 0x0fi8 #32 timer0_ctrl    !8 drop )
+
+    ( enable interrupts and start )
+    ien jmp start
+
+
+( host flags )
+isr_flags:
+    #8 0x81i8 #32 host_swled !8 drop
+
+    #32 host_flags @8
+    #32 host_swled !8
+    #32 host_flags !8 drop
+    ien ;
+
+
+( ps2 )
+isr_ps2:
+    #8 0x82i8 #32 host_swled !8 drop
+    ( Pull data )
+    #32 ps2_data @8
+    #32 host_swled !8 drop
+    ien ;
+
+
+( uart )
+isr_uart:
+    #8 0x83i8 #32 host_swled !8 drop
+    ( echo )
+    #32 uart_data @8
+    #32 uart_data !8 drop
+    ien ;
+
+
+( timer 0 )
+isr_timer0:
+    #8 0x84i8 #32 host_swled !8 drop
+    ( clear interrupt flag )
+    #32 timer0_ctrl @8
+    #32 timer0_ctrl !8 drop
+    ien ;
+
+
+( timer 1 )
+isr_timer1:
+    #8 0x85i8 #32 host_swled !8 drop
+    ( clear interrupt flag )
+    #32 timer1_ctrl @8
+    #32 timer1_ctrl !8 drop
+    ien ;
+
+
+( unknown )
+isr_unk:
+    #8 0xffi8 #32 host_swled !8 drop
+    jmp halt
+
+
+( ---------------------------------------------------------------------------- )
+( VGA subroutines )
+
+
+( ---------------------------------------------------------------------------- )
+( Host controller subroutines )
+
+
+( Print a byte to the seven-segment display upper byte )
+( b -- )
+seg_put_upper:
+    dup #8 0x0fi8 &        ( Extract lower nibble )
+    #32 seg_lut + @8       ( Look up segment value )
+    #32 host_sseg2 @8      ( Read existing value )
+    #8 0x80i8 &            ( Mask out only the decimal point )
+    |                      ( Combine with new segment values )
+    #32 host_sseg2 !8 drop ( Write back to segment register )
+
+    lsr lsr lsr lsr        ( Extract upper nibble )
+    #32 seg_lut + @8       ( Look up segment value )
+    #32 host_sseg3 @8      ( Read existing value )
+    #8 0x80i8 &            ( Mask out only decimal point )
+    |                      ( Combine with new segment values )
+    #32 host_sseg3 !8 drop ( Write back to segment register )
+
+    ;
+
+
+( Print a byte to the seven-segment display lower byte )
+( b -- )
+seg_put_lower:
+    dup #8 0x0fi8 &        ( Extract lower nibble )
+    #32 seg_lut + @8       ( Look up segment value )
+    #32 host_sseg0 @8      ( Read existing value )
+    #8 0x80i8 &            ( Mask out only the decimal point )
+    |                      ( Combine with new segment values )
+    #32 host_sseg0 !8 drop ( Write back to segment register )
+
+    lsr lsr lsr lsr        ( Extract upper nibble )
+    #32 seg_lut + @8       ( Look up segment value )
+    #32 host_sseg1 @8      ( Read existing value )
+    #8 0x80i8 &            ( Mask out only decimal point )
+    |                      ( Combine with new segment values )
+    #32 host_sseg1 !8 drop ( Write back to segment register )
+
+    ;
+
+
+( Clear the seven-segment display upper byte )
+( -- )
+seg_clr_upper:
+    #32 host_sseg2 @8 #8 0x7fi8 |  ( Read original value and clear all segments except point )
+    #32 host_sseg2 !8 drop         ( Write back into segment register )
+    #32 host_sseg3 @8 #8 0x7fi8 |  ( Read original value and clear all segments except point )
+    #32 host_sseg3 !8 drop         ( Write back into segment register )
+    ;
+
+
+( Clear the seven-segment display lower byte )
+( -- )
+seg_clr_upper:
+    #32 host_sseg0 @8 #8 0x7fi8 |  ( Read original value and clear all segments except point )
+    #32 host_sseg0 !8 drop         ( Write back into segment register )
+    #32 host_sseg1 @8 #8 0x7fi8 |  ( Read original value and clear all segments except point )
+    #32 host_sseg1 !8 drop         ( Write back into segment register )
+    ;
+
+
+( Turn on a decimal point on the seven-segment display )
+( n -- )
+seg_set_dp:
+    dup #8 0x03i8 - jn _seg_set_dp_x
+    #32 host_sseg0 +
+    dup @8 #8 0x7fi8 &
+    swap !8
+_seg_set_dp_x:
+    drop ;
+
+
+( Turn off a decimal point on the seven-segment display )
+( n -- )
+seg_clr_dp:
+    dup #8 0x03i8 - jn _seg_clr_dp_x
+    #32 host_sseg0 +
+    dup @8 #8 0x80i8 |
+    swap !8
+_seg_clr_dp_x:
+    drop ;
+
+
+seg_lut:
+    0x40i8 0x79i8 0x24i8 0x30i8
+    0x19i8 0x12i8 0x02i8 0x78i8
+    0x00i8 0x10i8 0x08i8 0x03i8
+    0x46i8 0x21i8 0x06i8 0x0ei8
+
+
+( ---------------------------------------------------------------------------- )
+( PS2 subroutines )
+
+
+( ---------------------------------------------------------------------------- )
+( UART subroutines )
+
+
+( Print a byte out the UART )
+( c -- )
+uart_putchar:
+    ( Wait for available space in the Tx FIFO )
+_uart_putchar_wait:
+    #32 uart_iflag @8
+    #8 0x04i8 & jz _uart_putchar_wait
+
+    ( Write byte to UART data register )
+    #32 uart_data !8 drop ;
+
+
+( Print an ASCIIZ string out the UART )
+( &s -- )
+uart_puts:
+_uart_puts_loop:
+    dup @8 dup jz _uart_puts_done
+    call uart_putchar
+    #8 0x01i8 + jmp _uart_puts_loop
+_uart_puts_done:
+    drop drop ;
+
+
+( ---------------------------------------------------------------------------- )
+( Entry point after reset )
+
+start:
+    #8 0x02i8 #32 host_swled !8 drop
+    ( Send greetz to the l33tz )
+    #32 greetz_uart call uart_puts
+    #8 0x03i8 #32 host_swled !8 drop
+
+    #32 greetz_uart call uart_puts
+    #8 0x04i8 #32 host_swled !8 drop
+
+    #8 0xa5i8 call seg_put_upper
+    #8 0xc3i8 call seg_put_lower
+    #8 0x02i8 call seg_set_dp
+
+    #8 "H"    #32 vga_scr #8 0i8  + !8 drop
+    #8 0x21i8 #32 vga_scr #8 1i8  + !8 drop
+    #8 "e"    #32 vga_scr #8 2i8  + !8 drop
+    #8 0x32i8 #32 vga_scr #8 3i8  + !8 drop
+    #8 "l"    #32 vga_scr #8 4i8  + !8 drop
+    #8 0x43i8 #32 vga_scr #8 5i8  + !8 drop
+    #8 "l"    #32 vga_scr #8 6i8  + !8 drop
+    #8 0x54i8 #32 vga_scr #8 7i8  + !8 drop
+    #8 "o"    #32 vga_scr #8 8i8  + !8 drop
+    #8 0x65i8 #32 vga_scr #8 9i8  + !8 drop
+    #8 "r"    #32 vga_scr #8 10i8 + !8 drop
+    #8 0x76i8 #32 vga_scr #8 11i8 + !8 drop
+    #8 "l"    #32 vga_scr #8 12i8 + !8 drop
+    #8 0x87i8 #32 vga_scr #8 13i8 + !8 drop
+    #8 "d"    #32 vga_scr #8 14i8 + !8 drop
+    #8 0x98i8 #32 vga_scr #8 15i8 + !8 drop
+    #8 "!"    #32 vga_scr #8 16i8 + !8 drop
+    #8 0xa9i8 #32 vga_scr #8 17i8 + !8 drop
+    #8 0x05i8 #32 host_swled !8 drop
+
+halt:
+    jmp halt
+
+
+greetz_uart:
+    "Hellorld," 0x20i8 "through" 0x20i8 "the" 0x20i8 "UART!" 0x0ai8 0x0di8 0x00i8
+
+greetz_vga:
+    "Hellorld," 0x20i8 "through" 0x20i8 "VGA!" 0x0ai8 0x0di8 0x00i8