-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcuts.fs
236 lines (172 loc) · 5.79 KB
/
cuts.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
\ *************************************
\ Block Driver
\ List of Structs:
\ off size what
\ 0 2 link to next node in list
\ 2 2 xt of get sector word
\ 4 2 xt of put sector word
\ 6 ??? ca of name of driver
\
\ Driver methods:
\ put sector ( addr lowsec hisec drive -- f )
\ get sector ( addr lowsec hisec drive -- f )
\
\ **************************************
l_head bdevs \ list head of block devices
: dev_>name ( a -- ca ) \ gets a devices name
6 + ;
: dev_get ( a l h d a -- ) \ executes dev's get sector word
2 + @ exec ;
: dev_put ( a l h d a -- ) \ executes dev's put sector word
4 + @ exec ;
: dev_by_name ( ca -- a ) \ gets a device struct addr by name
bdevs @ begin dup while 2dup dev_>name s= if nip exit then @ repeat nip ;
\
\ Drivewire Boisy/Becker Iface Block Device
\
{
: cksum ( addr -- x ) \ compute a 256 byte checksum
0 swap 100 for c@+ rot + swap next drop ;
: bkr! ( c -- ) \ send a byte via becker port
ff42 p! ;
: bkr@ ( -- c ) \ receive a byte via becker port
begin ff41 p@ until ff42 p@ ;
: getsec ( a l h d - f ) \ get a sector method
d2 bkr! bkr! bkr! sp@ c@ bkr! bkr! ( a -- )
dup 100 for bkr@ c!+ next drop
cksum sp@ c@ bkr! bkr!
bkr@
;
: putsec ( a l h d - f ) \ This just returns an error
2drop 2drop -1 ;
\ "create" the block device structure for this device
here
0 , \ list link
' getsec , \ xt to getsec
' putsec , \ xt to putsec
" dwbecker" s, \ string name
bdevs l_tail_add \ add to block drive list
}
\ ************************************
\ Filesystems
\ off size what
\ 0 2 list link
\ 2 2 xt to mount method
\ 4 2 xt to unmount method
\ 6 ?? string name of system
\ ************************************
l_head fsys \ list head of filesystems
: fsys_>name 6 + ;
: fsys_by_name ( ca -- a ) \ get filesystem struct by name
fsys @ begin dup while 2dup fsys_>name s= if nip exit then @ repeat nip ;
\ ***************************
\ RSDOS filesystem
\ ***************************
{
133 constant fat_sect \ the FAT sector
134 constant dir_sect \ the first DIR sector
20 constant dirent_size \ number of byte in DIR entry
9 constant sec/track \ sectors per granule
create dbuff 100 allot
create nbuff 14 allot
: mount ( a -- xt )
here
0 , \ list link
' mount , \ mount method
' umount , \ umount method
" rsdos" s, \ file system name
fsys l_tail_add \ add to filesystem list
}
\ ****************************************
\ Cell Buffer
\ This works as a queue a cell
\ based FIFO
\ ****************************************
0
cell field >head \ head offset of queue
cell field >size \ size of queue
cell field >msize \ max size of queue
struct buff
{
: applymask ( o buff -- o ) \ applies offset mask
>msize @ 1- and ;
: base ( buff - baddr ) \ returns base address of buffer
buff + ;
: haddr ( buff -- a ) \ returns real head address
dup base swap dup >head @ swap applymask cells + ;
: taddr ( buff -- a ) \ returns real tail address
dup haddr swap >size @ cells + ;
public
: full? ( buff -- f ) \ return true if channel is empty
dup >size @ swap >msize @ = ;
: empty? ( buff -- f ) \ return true if channel is full
>size @ 0= ;
: >b ( x buff -- ) \ put cell onto buffer
tuck taddr ! 1 swap >size +! ;
: b> ( buff -- x ) \ get cell from buffer
dup haddr @ swap dup -1 swap >size +! 1 swap +! ;
}
\ ***************************************
\ Channels
\ one-way asynchronous streaming IPC
\ ***************************************
{
8 constant BUFZ \ size of buffer in cells
BUFZ 1- constant MASK \ offset mask
0 ( this might be a dlist later... )
sema field >sema \ access semaphore
cell field >size \ how many bytes in buffer
cell field >pos \ input data pointer
cell field >writers \ writers waiting list
cell field >readers \ readers waiting list
BUFZ cells field >buffer \ data buffer
struct chan
: full? ( channel -- f ) \ flags true on buffer full
>size @ BUFZ = ;
: empty? ( channel -- f ) \ flags true on buffer empty
>size @ 0= ;
: fwait ( channel -- ) \ waits till channel is writeable
dup full?
if ioff
dup >sema release
>writers wait exit
then drop ;
: ewait ( channel -- ) \ waits till channel is readable
dup empty?
if ioff
dup >sema release
>readers wait exit
then drop ;
: head ( channel -- a ) \ fetches address to head of buffer
dup >buffer swap >pos @ MASK and cells + ;
: tail ( channel -- a ) \ fetches address to tail of buffer
dup head swap >size @ cells - ;
: inc ( channel -- ) \ increments buffer
1 over >size +! 1 swap >pos +! ;
: dec ( channel -- ) \ decrements buffer
-1 swap >size +! ;
: rwake ( channel -- ) \ wake read task
dup >readers l_dequeue dup
if wake drop exit
then drop >sema release ;
: wwake ( channel -- ) \ wake writer task
dup >writers l_dequeue dup
if wake drop exit
then drop >sema release ;
public
: ch! ( x channel -- ) \ send cell to channel
dup >sema lock \ lock channel
dup fwait \ wait until not full
tuck head ! \ data add to buffer
dup inc rwake ; \ inc pos and wake reader
: ch@ ( channel -- x ) \ get cell from channel
dup >sema lock \ lock channel
dup ewait \ wait until not empty
dup tail @ \ get data
swap dup dec \ inc dec pos
wwake ; \ wake writers
;
: channel ( "name" -- ) ( -- a ) \ creates an new channel
chan salloc dup constant
chan for false c!+ next drop ;
}