~vdupras/duskos

8b9d7966c05057d6d44ff8fc62e19e156e8abea8 — Virgil Dupras 7 days ago a98b630
rpi: Hello World!
3 files changed, 47 insertions(+), 16 deletions(-)

M fs/asm/arm.fs
M fs/doc/asm/arm.txt
M fs/xcomp/arm/rpi/kernel.fs
M fs/asm/arm.fs => fs/asm/arm.fs +8 -2
@@ 22,7 22,7 @@
: _ ( op r type -- op ) dip 4 lshift | << 1+ or 4 lshift or ;
: rlsl) 0 _ ; : rlsr) 1 _ ; : rasr) 2 _ ; : rror) 3 _ ;

: cond doer , does> @ 28 lshift swap $0fffffff and ;
: cond doer , does> @ 28 lshift swap $0fffffff and or ;
0 cond eq)         1 cond ne)          2 cond cs)          3 cond cc)
4 cond mi)         5 cond pl)          6 cond vs)          7 cond vc)
8 cond hi)         9 cond ls)          10 cond ge)         11 cond lt)


@@ 34,6 34,8 @@
8 op tst)          9 op teq)           10 op cmp)          11 op cmn)
12 op orr)         13 op mov)          14 op bic)          15 op mvn)

: f) $00100000 or ;

: #? ( n -- immop rest )
  r! dup if log2 then 7 - max0 dup 1 and if 1+ then ( shift ) \ V1=n
  r@ over rshift ( shift b )


@@ 57,6 59,10 @@ $e5000000 const str)         $e5100000 const ldr)
: !) $00200000 or ;

\ Branching
: b) ( rel32 -- op ) >> >> 2 - $ffffff and $ea000000 or ;
: _rel>off >> >> 2 - $ffffff and ;
: b) ( rel32 -- op ) _rel>off $ea000000 or ;
: bl) b) $01000000 or ;
: bx) ( r -- op ) $e12fff10 or ;

: forward! ( jmpaddr -- )
  here over - _rel>off over le@ $ff000000 and or swap le! ;

M fs/doc/asm/arm.txt => fs/doc/asm/arm.txt +5 -0
@@ 53,6 53,11 @@ All those instructions except mov) and mvn) have 3 operators:
    and) eor) sub) rsb) add) adc) sbc) rsc)
    tst) teq) cmp) cmn) orr) mov) bic) mvn)

rn) shouldn't be used with mov) and mvn)

To have the operation set the CPSR flags, you can use the word f) which sets the
"S" bit of the instruction.

## Single Data Transfer

The str) and ldr) operations only use rd) and rn), with rd) being the register

M fs/xcomp/arm/rpi/kernel.fs => fs/xcomp/arm/rpi/kernel.fs +34 -14
@@ 25,40 25,60 @@ $84 const UART0_ITIP
$88 const UART0_ITOP
$8c const UART0_TDR

$8000 to binstart
: values ( n -- ) for 0 value next ;
2 values lblemit lblmsg

$10000 to binstart
0 align4 here to org
forward b) ,)
pc to lblmsg ," Hello World!\0" 0 align4
pc to lblemit \ r0=char
  pc
    ldr) r1 rd) r7 rn) UART0_FR +i) ,)
    tst) r1 rn) $20 i) f) ,)
    b) ne) ,)
  str) r0 rd) r7 rn) UART0_DR +i) ,)
  mov) rPC rd) rLR rm) ,)
forward!
mov) r0 rd) MMIO_BASE i) ,) \ r0 = MMIO_BASE
add) r0 rd) r0 rn) GPIO_BASE i) ,) \ r0 = GPIO_BASE
add) r2 rd) r0 rn) UART0_BASE i) ,) \ r2 = UART0_BASE
add) r8 rd) r0 rn) GPIO_BASE i) ,) \ r8 = GPIO_BASE
add) r7 rd) r8 rn) UART0_BASE i) ,) \ r7 = UART0_BASE
\ Disable UART0
mov) r1 rd) 0 i) ,) str) r1 rd) r2 rn) UART0_CR +i) ,)
mov) r1 rd) 0 i) ,) str) r1 rd) r7 rn) UART0_CR +i) ,)
\ Disable pull up/down for all GPIO pins & delay for 150 cycles.
( r1=0 ) str) r1 rd) r0 rn) GPPUD +i) ,)
( r1=0 ) str) r1 rd) r8 rn) GPPUD +i) ,)
\ TODO: add delay
\ Disable pull up/down for pin 14,15 & delay for 150 cycles.
mov) r1 rd) $c000 i) ,) str) r1 rd) r0 rn) GPPUDCLK0 +i) ,)
mov) r1 rd) $c000 i) ,) str) r1 rd) r8 rn) GPPUDCLK0 +i) ,)
\ TODO: add delay
\ Write 0 to GPPUDCLK0 to make it take effect.
mov) r1 rd) 0 i) ,) str) r1 rd) r0 rn) GPPUDCLK0 +i) ,)
mov) r1 rd) 0 i) ,) str) r1 rd) r8 rn) GPPUDCLK0 +i) ,)
\ Clear pending interrupts.
mov) r1 rd) $700 i) ,) add) r1 rd) r1 rn) $ff i) ,)
str) r1 rd) r2 rn) UART0_ICR +i) ,)
str) r1 rd) r7 rn) UART0_ICR +i) ,)
\ Set integer & fractional part of baud rate.
\ Divider = UART_CLOCK/(16 * Baud)
\ Fraction part register = (Fractional part * 64) + 0.5
\ Baud = 115200.
\ Divider = 3000000 / (16 * 115200) = 1.627 = ~1.
mov) r1 rd) 1 i) ,) str) r1 rd) r2 rn) UART0_IBRD +i) ,)
mov) r1 rd) 1 i) ,) str) r1 rd) r7 rn) UART0_IBRD +i) ,)
\ Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
mov) r1 rd) 40 i) ,) str) r1 rd) r2 rn) UART0_FBRD +i) ,)
mov) r1 rd) 40 i) ,) str) r1 rd) r7 rn) UART0_FBRD +i) ,)
\ Enable FIFO & 8 bit data transmission (1 stop bit, no parity).
mov) r1 rd) $70 i) ,) str) r1 rd) r2 rn) UART0_LCRH +i) ,)
mov) r1 rd) $70 i) ,) str) r1 rd) r7 rn) UART0_LCRH +i) ,)
\ Mask all interrupts.
mov) r1 rd) $700 i) ,) add) r1 rd) r1 rn) $f2 i) ,)
str) r1 rd) r2 rn) UART0_IMSC +i) ,)
str) r1 rd) r7 rn) UART0_IMSC +i) ,)
\ Enable UART0, receive & transfer part of UART.
mov) r1 rd) $300 i) ,) add) r1 rd) r1 rn) $01 i) ,)
str) r1 rd) r2 rn) UART0_CR +i) ,)
str) r1 rd) r7 rn) UART0_CR +i) ,)

mov) r1 rd) 'X' i) ,) str) r1 rd) r2 rn) UART0_DR +i) ,)
mov) r6 rd) binstart i) ,)
add) r6 rd) r6 rn) lblmsg binstart - i) ,)
ldr) r0 rd) r6 rn) 8b) 1 +i) post) ,)
pc
  lblemit abs>rel bl) ,)
  ldr) r0 rd) r6 rn) 8b) 1 +i) post) ,)
  teq) r0 rn) 0 i) f) ,)
  abs>rel b) ne) ,)
0 b) ,)