-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommon.fs
66 lines (62 loc) · 2.66 KB
/
common.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
\ #require memmap.fs
\ #require bitfields.fs
\ helpers
: _width-to-mask ( width -- mask ) #1 swap lshift #1 - 1-foldable 1-foldable ;
: _offset-width-to-mask ( offset width -- mask ) _width-to-mask swap lshift 2-foldable ;
\ Bitfields manipulation: bitfields are represented by a triplet of:
\ * register address offset from peripheral address (defined in memmap.fs)
\ * bit offset
\ * bit width
\ The bitfield words defined in bitfields.fs leave the
\ corresponding triplet on the stack. The following words perform an action
\ using a peripheral address and a bitfield triplet from the stack.
: bfs! ( addr addr-offset bit-offset width -- ) \ set all bitfield bits
_offset-width-to-mask -rot + bis!
;
: bfc! ( addr addr-offset bit-offset width -- ) \ clear all bitfield bits
_offset-width-to-mask -rot + bic!
;
: bf! ( u addr addr-offset bit-offset width -- ) \ store value in bitfield
over >R \ save a copy of bit-offset
_offset-width-to-mask \ get a mask ( u addr addr-offset mask, R: bit-offset )
-rot + rot \ calc address and move u to top ( mask addr u, R: bit-offset )
R> lshift \ shift u to proper position ( mask addr u-shifted )
rot dup not >R \ ( addr u-shifted mask, R: mask-inverted )
and \ ( addr u-shifted-masked, R: mask-inverted )
swap dup \ ( u-shifted-masked addr addr, R: mask-inverted )
@ R> and \ ( u-shifted-masked addr val-from-addr-masked )
rot or swap !
;
: bf@ ( addr addr-offset bit-offset width -- u ) \ fetch value from bitfield
over >R \ save a copy of bit-offset
_offset-width-to-mask
-rot + \ move mask out of way and calc address ( mask addr, R: bit-offset )
@ and R> rshift \ fetch value and mask it then rshift by bit-offset
;
: bf. ( addr addr-offset bit-offset width -- u ) \ print value from bitfield
bf@ .
;
: bfh. ( addr addr-offset bit-offset width -- ) \ print value from bitfield in hex
base @ >R hex bf. R> base !
;
: bfb. ( addr addr-offset bit-offset width -- ) \ print value from bitfield in binary
base @ >R binary bf. R> base !
;
: bfm ( addr-offset bit-offset width -- mask )
_offset-width-to-mask swap drop 3-foldable
;
: bf<< ( u addr-offset bit-offset width -- ) \ shift value into bitfield position and mask
rot drop \ do not need addr-offset
over swap \ save a copy of bit-offset
_offset-width-to-mask
-rot
lshift and
;
\ convenience words for printing in different formats without having the side
\ effect of changing the base for future words
: h. base @ >R hex . R> base ! ; \ print in hex
: b. base @ >R binary . R> base ! ; \ print in binary
: hu. base @ >R hex u. R> base ! ; \ print in hex, unsigned
: init ( -- ) \ called automatically after reset
." common initialized" cr
;