-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHAT.dasm
More file actions
287 lines (223 loc) · 8.37 KB
/
Copy pathHAT.dasm
File metadata and controls
287 lines (223 loc) · 8.37 KB
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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
; Implementation of the HAT File System for use in PaC OS
; As specified by the community DCPU-16 standards
; https://github.com/0x10cStandardsCommittee/0x10c-Standards/blob/master/FS/Draft_Harrys_Allocation_Table.txt
; ===============================
; TESTS / USAGE EXAMPLE
JSR HAT_format ; format the drive to use HAT
SET [ROOT], A
SET A, bin_folder ; Add a bin folder to the root.
SET B, [ROOT]
JSR HAT_mkdir
SET A, usr_folder
SET B, [ROOT]
JSR HAT_mkdir
:crash SET PC, crash
:ROOT DAT 0x0000, 0x0000
:bin_folder DAT "bin", 0x0000
:usr_folder DAT "usr", 0x0000
; ================================
:s_HATdriver
:HAT_VERSION DAT 0x4001
;A inode* HAT_format(void)
; Formats a section of memory to be used as a HAT file system.
; Returns a pointer to the root inode.
:HAT_format
; Set up header information
; will eventually calculate sector sizes and amounts using disk size...
SET [_hat_version], [HAT_VERSION]
SET [_num_sectors], 192 ; 192 sectors each 128 bytes takes up 0x6000
SET [_sector_size], 128
SET [_sector_map_start], s_HATsector_map
SET [_sector_joins_start], s_HATsector_joins
SET [_sectors_start], s_HATsectors
SET [_sectors_used], 0
JSR HAT_createDirInode ; create the root inode.
SET PC, POP
;A inode* HAT_createInode(void)
; Creates a new inode in the first available sector of a directory type
; and returns a pointer to the created inode.
:HAT_createDirInode
JSR HAT_takeSector
SET [A], 1 ;mark inode as a directory.
SET [A+1], 0 ;new inode has no links pointing to it.
SET [A+2], 0 ;inode is initialized to empty.
SET PC, POP
;A bitmap* HAT_getSectorJoin(A sector* sector)
; Gets the sector joins bitmap corresponding to the given sector.
:HAT_getSectorJoin
SUB A, [_sectors_start]
DIV A, [_sector_size]
ADD A, [_sector_joins_start]
SET PC, POP
;A addr HAT_findEnd(A inode* inode)
; Find the first unoccupied byte in the data area for this given inode. If there is
; no room left in the sector, a join will be created and the starting address of
; the new sector will be returned.
:HAT_findEnd
SET PUSH, X
SET PUSH, Y
:_loop__findEnd
SET X, A
JSR HAT_getSectorJoin
IFE [A], 0x0000
SET PC, _found__findEnd
SET A, [A]
SET PC, _loop__findEnd
:_found__findENd ; Found last used sector in the stripe.
SET A, X
ADD A, [X+2]
ADD A, 4
SET Y, A
SUB Y, [_sector_size]
IFE Y, X
SET PC, _overflow__findEnd
SET PC, _done__findEnd
:_overflow__findENd ; Last sector in strip is full, need to reserve a new one.
SET A, X
JSR HAT_createJoin
:_done__findENd
SET Y, POP
SET X, POP
SET PC, POP
;A sector* HAT_createJoin(A sector* inode)
; Reserves a new sector and joins the given sector to it.
; Returns the address of the new sector.
:HAT_createJoin
SET PUSH, X
SET X, A
JSR HAT_takeSector ; Reserve new sector
SET PUSH, X
SET X, A
SET A, POP
JSR HAT_getSectorJoin ; Get the sector join for this sector
SET [A], X ; Set the sector join for this sector to the new sector
SET A, X ; Return the new sector address.
SET X, POP
SET PC, POP
;void HAT_createLink(A inode* parent, B inode* child, C string* filename)
; Adds a new link to the given parent inode pointing to the given child
; inode with the given filename.
:HAT_createLink
SET PUSH, X
SET PUSH, Y
SET PUSH, A
JSR HAT_findEnd
SET X, A
SET A, POP
SET [X], B ; Set strip start sector address
ADD [A+1], 1 ; increase parent inode link count.
ADD [A+2], 16 ; increase parent content size by 16 bytes (size of link)
ADD X, 1
SET Y, 0 ; Count of how many characters have been copied
:_loop__HAT_createLink
IFE Y, 15
SET PC, _done__HAT_createLink ; stop copying if max reached.
IFE [C], 0x0000
SET PC, _done__HAT_createLink ; stop copying if end of string reached.
SET [X], [C]
ADD X, 1
ADD C, 1
ADD Y, 1
SET PC, _loop__HAT_createLink
:_done__HAT_createLink
SET Y, POP
SET X, POP
SET PC, POP
;void HAT_mkdir(A string* name, B inode* directory)
; Creates a new directory with a givin name in a given directory
:HAT_mkdir
SET C, A
JSR HAT_createDirInode
SET PUSH, A
SET A, B
SET B, POP
JSR HAT_createLink
SET PC, POP
;A sector* HAT_takeSector(void)
; Finds the first unused sector, marks it as used and returns a pointer to it.
:HAT_takeSector
SET PUSH, X
SET PUSH, Y
SET X, s_HATsector_map
SET Y, 0x8000
:_loop__HAT_takeSector
SET A, [X]
AND A, Y
IFE A, 0x0000
SET PC, _found__HAT_takeSector
IFE Y, 0x0001
SET PC, _next__HAT_takeSector
SHR Y, 0x0001
SET PC, _loop__HAT_takeSector
:_next__HAT_takeSector
SET Y, 0x8000
ADD X, 1
IFE X, s_HATsector_joins ; We reached the joins table! HAT FS must be full.
SET PC, _done__HAT_takeSector
SET PC, _loop__HAT_takeSector
:_found__HAT_takeSector
BOR [X], Y ; mark this sector as used.
SUB X, s_HATsector_map ; calculate sector offset due to which byte a space was found in.
MUL X, [_sector_size]
MUL X, 16
SET A, 0 ; calculate sector offset due to which bit a space was found in.
:_loop2__HAT_takeSector
SHL Y, 0x0001
IFE Y, 0x0000
SET PC, _dloop2__HAT_takeSector
ADD A, 1
SET PC, _loop2__HAT_takeSector
:_dloop2__HAT_takeSector
MUL A, [_sector_size]
ADD A, X ; combine the two offsets together
ADD A, s_HATsectors
:_done__HAT_takeSector
SET Y, POP
SET X, POP
SET PC, POP
; INODE STRUCTURE:
; 1 | type -> (0 unused, 1 directory, 2 file)
; 1 | num_links
; 2 | content_size
; LINK STRUCTURE
; 1 | strip_start_sector
; 15 | filename (alphanumeric, periods, and underscores). Unused must be set to 0.
:s_HATheader
:_hat_version DAT 0x4001
:_num_sectors DAT 0x0000
:_sector_map_start DAT 0x0000, 0x0000
:_sector_joins_start DAT 0x0000, 0x0000
:_sectors_start DAT 0x0000, 0x0000
:_sector_size DAT 0x0000
:_sectors_used DAT 0x0000
:s_HATsector_map ;reserve sector map space (num_sectors / 16 bytes)
DAT 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000
:s_HATsector_joins ;reseerve sector joins table space (num_sectors bytes)
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
DAT 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
:s_HATsectors ;sectors area (needs num_sectors * sector_size bytes)