( 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 0x03i8 #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 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 0x13i8 #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
( VGA subroutines )
+cursor_loc=0x01000000
+cursor_col=0x01000004
+
+
+( Set up the cursor position and color )
+( -- )
+console_init:
+ #8 0x00i8 #32 cursor_loc !32 drop ( Set the cursor to the beginning of the screen )
+ #8 0x3bi8 #32 cursor_col !8 drop ( Set the cursor color to light blue on dark blue )
+ #32 vga_scr #32 0x00003b20i32 #32 4800i32 call mem_set_16
+ ;
+
+
+( Print a character to the VGA display )
+( c -- )
+console_putc:
+ #32 vga_scr #32 cursor_loc @32 + dup >r
+ !8 drop
+ #32 cursor_col @8 r> #8 1i8 + !8 drop
+ #32 cursor_loc dup @32 #8 0x02i8 + swap !32 drop
+ ;
+
+
+( Print an ASCIIZ string out the VGA display )
+( &s -- )
+console_puts:
+_console_puts_loop:
+ dup @8 dup jz _console_puts_done
+ call console_putc
+ #8 0x01i8 + jmp _console_puts_loop
+_console_puts_done:
+ drop drop ;
+
+
( ---------------------------------------------------------------------------- )
( Host controller subroutines )
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 )
+ #8 0x80i8 & | ( Mask out only the decimal point and combine )
#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 )
+ #8 0x80i8 & | ( Mask out only decimal point and combine )
#32 host_sseg3 !8 drop ( Write back to segment register )
;
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 )
+ #8 0x80i8 & | ( Mask out only the decimal point and combine )
#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 )
+ #8 0x80i8 & | ( Mask out only decimal point and combine )
#32 host_sseg1 !8 drop ( Write back to segment register )
;
( Print a byte out the UART )
( c -- )
-uart_putchar:
+uart_putc:
( Wait for available space in the Tx FIFO )
-_uart_putchar_wait:
+_uart_putc_wait:
#32 uart_iflag @8
- #8 0x04i8 & jz _uart_putchar_wait
+ #8 0x04i8 & jz _uart_putc_wait
( Write byte to UART data register )
#32 uart_data !8 drop ;
uart_puts:
_uart_puts_loop:
dup @8 dup jz _uart_puts_done
- call uart_putchar
+ call uart_putc
#8 0x01i8 + jmp _uart_puts_loop
_uart_puts_done:
drop drop ;
+( ---------------------------------------------------------------------------- )
+( Utility subroutines )
+
+
+( Copy block of bytes, allowing for overlap )
+( src dest count -- )
+mem_move:
+ >r
+ >r dup r> swap
+ >r dup r> swap
+ - ( dest-src )
+ dup jz _mem_move_none
+ jp _mem_move_back
+
+ ( Copy the block front-to-back )
+_mem_move_front_loop:
+ r@ jz _mem_move_done
+ >r dup @8 r@ !8 drop
+ #8 1i8 + r> #8 1i8 +
+ #8 1i8 r> - >r
+ jmp _mem_move_front_loop
+
+_mem_move_back:
+ ( Copy the block back-to-front )
+ r@ swap >r +
+ r> r@ +
+_mem_move_back_loop:
+ r@ jz _mem_move_done
+ #8 1i8 swap -
+ >r #8 1i8 swap -
+ dup @8 r@ !8 drop r>
+ #8 1i8 r> - >r
+ jmp _mem_move_back_loop
+
+_mem_move_none:
+ drop
+_mem_move_done:
+ r> drop drop drop ;
+
+
+( Fill a block of memory with bytes )
+( dest value count -- )
+mem_set_8:
+ >r
+_mem_set_8_loop:
+ r@ jz _mem_set_8_done
+ >r dup r> swap !8
+ >r #8 1i8 + r>
+ #8 1i8 r> - >r
+ jmp _mem_set_8_loop
+_mem_set_8_done:
+ r> drop drop drop ;
+
+
+( Fill a block of memory with 16-bit values )
+( dest value count -- )
+mem_set_16:
+ >r
+_mem_set_16_loop:
+ r@ jz _mem_set_16_done
+ >r dup r@ swap !8 drop
+ #8 1i8 + dup r@ lsr lsr lsr lsr lsr lsr lsr lsr swap !8 drop
+ #8 1i8 + r>
+ #8 1i8 r> - >r
+ jmp _mem_set_16_loop
+_mem_set_16_done:
+ r> drop 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
+ call console_init
+ #32 greetz_vga call console_puts
halt:
- jmp halt
+ #8 0xc0i8 #32 host_swled !8 drop
+_halt:
+ jmp _halt
greetz_uart: