Skip to content

Commit 45abc1a

Browse files
basic bitops
1 parent 62c4b22 commit 45abc1a

9 files changed

Lines changed: 222 additions & 47 deletions

File tree

.idea/copyright/Open_Source.xml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

include/basic/context.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -330,11 +330,6 @@ typedef struct basic_ctx {
330330
*/
331331
buddy_allocator_t* allocator;
332332

333-
queued_udp_packet* udp_packets[65536];
334-
queued_udp_packet* udp_list_tail[65536];
335-
336-
spinlock_t udp_read_lock;
337-
338333
queued_udp_packet last_packet;
339334
} basic_ctx;
340335

include/basic/lowlevel.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,26 @@ int64_t basic_inport(struct basic_ctx* ctx);
115115

116116
int64_t basic_inportw(struct basic_ctx* ctx);
117117

118-
int64_t basic_inportd(struct basic_ctx* ctx);
118+
int64_t basic_inportd(struct basic_ctx* ctx);
119+
120+
int64_t basic_bitor(struct basic_ctx* ctx);
121+
122+
int64_t basic_bitand(struct basic_ctx* ctx);
123+
124+
int64_t basic_bitnot(struct basic_ctx* ctx);
125+
126+
int64_t basic_biteor(struct basic_ctx* ctx);
127+
128+
int64_t basic_bitnand(struct basic_ctx* ctx);
129+
130+
int64_t basic_bitnor(struct basic_ctx* ctx);
131+
132+
int64_t basic_bitxnor(struct basic_ctx* ctx);
133+
134+
int64_t basic_bitshl(struct basic_ctx* ctx);
135+
136+
int64_t basic_bitshr(struct basic_ctx* ctx);
137+
138+
int64_t basic_bitrol(struct basic_ctx* ctx);
139+
140+
int64_t basic_bitror(struct basic_ctx* ctx);

os/programs/drivers/ps2mouse.rrbasic

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,14 @@ done = 0
66
spins = 0
77
WHILE spins < 64 AND done = 0
88
s = INPORT(&64)
9-
IF (s AND 1) <> 0 AND (s AND &20) <> 0 THEN
9+
IF BITAND(s, 1) <> 0 AND BITAND(s, &20) <> 0 THEN
1010
discard = INPORT(&60)
1111
ELSE
1212
done = 1
1313
ENDIF
1414
spins = spins + 1
1515
ENDWHILE
1616

17-
OUTPORT &64, &20
18-
cmd = INPORT(&60)
19-
cmd = cmd OR &10
20-
OUTPORT &64, &60
21-
OUTPORT &60, cmd
22-
2317
OUTPORT &64, &A8
2418

2519
ok = FNmouse_send(&FF)
@@ -35,7 +29,7 @@ idx = 0
3529
WHILE TRUE
3630
b = FNread_mouse_byte
3731
IF b >= 0 THEN
38-
valid_first = NOT (idx = 0 AND (b AND 8) = 0)
32+
valid_first = NOT (idx = 0 AND BITAND(b, 8) = 0)
3933
IF valid_first = 1 THEN
4034
pkt(idx) = b
4135
idx = idx + 1
@@ -47,17 +41,17 @@ WHILE TRUE
4741

4842
dx = b1
4943
dy = b2
50-
IF (b0 AND &10) <> 0 THEN
44+
IF BITAND(b0, &10) <> 0 THEN
5145
dx = dx - 256
5246
ENDIF
53-
IF (b0 AND &20) <> 0 THEN
47+
IF BITAND(b0, &20) <> 0 THEN
5448
dy = dy - 256
5549
ENDIF
5650

5751
x = x + dx
5852
y = y - dy
5953

60-
buttons = b0 AND 7
54+
buttons = BITAND(b0, 7)
6155

6256
idx = 0
6357
ENDIF
@@ -84,17 +78,17 @@ ENDPROC
8478

8579
DEF PROCwait_ibf_clear(max_spins)
8680
spins = 0
87-
WHILE (INPORT(&64) AND 2) <> 0 AND spins < max_spins
81+
WHILE BITAND(INPORT(&64), 2) <> 0 AND spins < max_spins
8882
spins = spins + 1
8983
ENDWHILE
9084
ENDPROC
9185

9286
DEF FNread_mouse_byte
9387
s = INPORT(&64)
94-
IF (s AND 1) = 0 THEN
88+
IF BITAND(s, 1) = 0 THEN
9589
= -1
9690
ENDIF
97-
IF (s AND &20) = 0 THEN
91+
IF BITAND(s, &20) = 0 THEN
9892
= -1
9993
ENDIF
10094
= INPORT(&60)

os/programs/rocketsh.rrbasic

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
REM *** Retro Rocket BASIC Shell ***
22
LIBRARY LIB$ + "/ansi"
33

4-
ON ERROR PROCerrorHandler
4+
REM ON ERROR PROCerrorHandler
55

66
PROCEdInit(TRUE)
77

src/basic/function.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ struct basic_int_fn builtin_int[] =
6969
{ basic_inportd, "INPORTD" },
7070
{ basic_inport, "INPORT" },
7171
{ basic_udplastsourceport, "UDPLASTSOURCEPORT" },
72+
{ basic_bitor, "BITOR" },
73+
{ basic_bitand, "BITAND" },
74+
{ basic_biteor, "BITEOR" },
75+
{ basic_bitnot, "BITNOT" },
76+
{ basic_bitnand, "BITNAND" },
77+
{ basic_bitxnor, "BITXNOR" },
78+
{ basic_bitshl, "BITSHL" },
79+
{ basic_bitshr, "BITSHR" },
80+
{ basic_bitrol, "BITROL" },
81+
{ basic_bitror, "BITROR" },
7282
{ NULL, NULL },
7383
};
7484

src/basic/lowlevel.c

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,154 @@ void outportd_statement(struct basic_ctx* ctx) {
212212
accept_or_return(NEWLINE, ctx);
213213
outl(port & 0xFFFF, value);
214214
}
215+
216+
int64_t basic_bitor(struct basic_ctx* ctx)
217+
{
218+
PARAMS_START;
219+
PARAMS_GET_ITEM(BIP_INT);
220+
int64_t op1 = intval;
221+
PARAMS_GET_ITEM(BIP_INT);
222+
int64_t op2 = intval;
223+
PARAMS_END("BITOR", -1);
224+
return op1 | op2;
225+
}
226+
227+
int64_t basic_bitand(struct basic_ctx* ctx)
228+
{
229+
PARAMS_START;
230+
PARAMS_GET_ITEM(BIP_INT);
231+
int64_t op1 = intval;
232+
PARAMS_GET_ITEM(BIP_INT);
233+
int64_t op2 = intval;
234+
PARAMS_END("BITAND", -1);
235+
return op1 & op2;
236+
}
237+
238+
int64_t basic_bitnot(struct basic_ctx* ctx)
239+
{
240+
PARAMS_START;
241+
PARAMS_GET_ITEM(BIP_INT);
242+
int64_t op1 = intval;
243+
PARAMS_END("BITNOT", -1);
244+
return ~op1;
245+
}
246+
247+
int64_t basic_biteor(struct basic_ctx* ctx)
248+
{
249+
PARAMS_START;
250+
PARAMS_GET_ITEM(BIP_INT);
251+
int64_t op1 = intval;
252+
PARAMS_GET_ITEM(BIP_INT);
253+
int64_t op2 = intval;
254+
PARAMS_END("BITEOR", -1);
255+
return op1 ^ op2;
256+
}
257+
258+
int64_t basic_bitnand(struct basic_ctx* ctx)
259+
{
260+
PARAMS_START;
261+
PARAMS_GET_ITEM(BIP_INT);
262+
int64_t op1 = intval;
263+
PARAMS_GET_ITEM(BIP_INT);
264+
int64_t op2 = intval;
265+
PARAMS_END("BITNAND", -1);
266+
return ~(op1 & op2);
267+
}
268+
269+
int64_t basic_bitnor(struct basic_ctx* ctx)
270+
{
271+
PARAMS_START;
272+
PARAMS_GET_ITEM(BIP_INT);
273+
int64_t op1 = intval;
274+
PARAMS_GET_ITEM(BIP_INT);
275+
int64_t op2 = intval;
276+
PARAMS_END("BITNOR", -1);
277+
return ~(op1 | op2);
278+
}
279+
280+
int64_t basic_bitxnor(struct basic_ctx* ctx)
281+
{
282+
PARAMS_START;
283+
PARAMS_GET_ITEM(BIP_INT);
284+
int64_t op1 = intval;
285+
PARAMS_GET_ITEM(BIP_INT);
286+
int64_t op2 = intval;
287+
PARAMS_END("BITXNOR", -1);
288+
return ~(op1 ^ op2);
289+
}
290+
291+
int64_t basic_bitshl(struct basic_ctx* ctx)
292+
{
293+
PARAMS_START;
294+
PARAMS_GET_ITEM(BIP_INT);
295+
int64_t val = intval;
296+
PARAMS_GET_ITEM(BIP_INT);
297+
int64_t n = intval;
298+
PARAMS_END("BITSHL", -1);
299+
300+
uint64_t u = (uint64_t) val;
301+
if (n < 0) n = 0;
302+
if (n > 63) n = 63;
303+
304+
u = u << (unsigned)n;
305+
return (int64_t) u;
306+
}
307+
308+
int64_t basic_bitshr(struct basic_ctx* ctx)
309+
{
310+
PARAMS_START;
311+
PARAMS_GET_ITEM(BIP_INT);
312+
int64_t val = intval;
313+
PARAMS_GET_ITEM(BIP_INT);
314+
int64_t n = intval;
315+
PARAMS_END("BITSHR", -1);
316+
317+
uint64_t u = (uint64_t) val; /* logical right shift */
318+
if (n < 0) n = 0;
319+
if (n > 63) n = 63;
320+
321+
u = u >> (unsigned)n;
322+
return (int64_t) u;
323+
}
324+
325+
int64_t basic_bitrol(struct basic_ctx* ctx)
326+
{
327+
PARAMS_START;
328+
PARAMS_GET_ITEM(BIP_INT);
329+
int64_t val = intval;
330+
PARAMS_GET_ITEM(BIP_INT);
331+
int64_t n = intval;
332+
PARAMS_GET_ITEM(BIP_INT);
333+
int64_t width = intval;
334+
PARAMS_END("BITROL", -1);
335+
336+
uint64_t w = (width <= 0 || width > 64) ? 64u : (uint64_t) width;
337+
uint64_t mask = (w == 64u) ? ~0ULL : ((1ULL << w) - 1ULL);
338+
339+
uint64_t k = (uint64_t) ((n % (int64_t)w + (int64_t)w) % (int64_t)w);
340+
uint64_t x = (uint64_t) val & mask;
341+
342+
uint64_t out = ((x << k) | (x >> (w - k))) & mask;
343+
return (int64_t) out;
344+
}
345+
346+
int64_t basic_bitror(struct basic_ctx* ctx)
347+
{
348+
PARAMS_START;
349+
PARAMS_GET_ITEM(BIP_INT);
350+
int64_t val = intval;
351+
PARAMS_GET_ITEM(BIP_INT);
352+
int64_t n = intval;
353+
PARAMS_GET_ITEM(BIP_INT);
354+
int64_t width = intval;
355+
PARAMS_END("BITROR", -1);
356+
357+
uint64_t w = (width <= 0 || width > 64) ? 64u : (uint64_t) width;
358+
uint64_t mask = (w == 64u) ? ~0ULL : ((1ULL << w) - 1ULL);
359+
360+
uint64_t k = (uint64_t) ((n % (int64_t)w + (int64_t)w) % (int64_t)w);
361+
uint64_t x = (uint64_t) val & mask;
362+
363+
uint64_t out = ((x >> k) | (x << (w - k))) & mask;
364+
return (int64_t) out;
365+
}

src/basic/main.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,7 @@ struct basic_ctx *basic_init(const char *program, uint32_t pid, const char *file
171171
ctx->debug_status = 0;
172172
ctx->debug_breakpoints = NULL;
173173
ctx->debug_breakpoint_count = 0;
174-
memset(ctx->udp_packets, 0, sizeof(ctx->udp_packets));
175-
memset(ctx->udp_list_tail, 0, sizeof(ctx->udp_list_tail));
176-
memset(&ctx->last_packet, 0, sizeof(ctx->last_packet));
177-
init_spinlock(&ctx->udp_read_lock);
174+
memset(&ctx->last_packet, 0, sizeof(queued_udp_packet));
178175
ctx->if_nest_level = 0;
179176
ctx->errored = false;
180177
ctx->error_handler = NULL;
@@ -386,10 +383,7 @@ struct basic_ctx *basic_clone(struct basic_ctx *old) {
386383
ctx->current_token = NO_TOKEN;
387384
ctx->error_handler = old->error_handler;
388385
ctx->sleep_until = old->sleep_until;
389-
memset(ctx->udp_packets, 0, sizeof(ctx->udp_packets));
390-
memset(ctx->udp_list_tail, 0, sizeof(ctx->udp_list_tail));
391-
memset(&ctx->last_packet, 0, sizeof(ctx->last_packet));
392-
init_spinlock(&ctx->udp_read_lock);
386+
memset(&ctx->last_packet, 0, sizeof(queued_udp_packet));
393387
ctx->int_variables = old->int_variables;
394388
ctx->str_variables = old->str_variables;
395389
ctx->eval_linenum = old->eval_linenum;

src/basic/sockets.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
*/
55
#include <kernel.h>
66

7+
static queued_udp_packet* udp_packets[65536] = {0};
8+
static queued_udp_packet* udp_list_tail[65536] = {0};
9+
static spinlock_t udp_read_lock = 0;
10+
711
/**
812
* @brief Idle callback to check if socket is ready to read.
913
*
@@ -255,16 +259,16 @@ static void basic_udp_handle_packet(uint32_t src_ip, uint16_t src_port, uint16_t
255259
packet->source_port = src_port;
256260
packet->next = NULL;
257261
uint64_t flags;
258-
lock_spinlock_irq(&ctx->udp_read_lock, &flags);
259-
packet->prev = (struct queued_udp_packet*)ctx->udp_list_tail[dst_port];
260-
if (ctx->udp_list_tail[dst_port] == NULL) {
261-
ctx->udp_list_tail[dst_port] = packet;
262-
ctx->udp_packets[dst_port] = packet;
262+
lock_spinlock_irq(&udp_read_lock, &flags);
263+
packet->prev = (struct queued_udp_packet*)udp_list_tail[dst_port];
264+
if (udp_list_tail[dst_port] == NULL) {
265+
udp_list_tail[dst_port] = packet;
266+
udp_packets[dst_port] = packet;
263267
} else {
264-
ctx->udp_list_tail[dst_port]->next = (struct queued_udp_packet*)packet;
265-
ctx->udp_list_tail[dst_port] = packet;
268+
udp_list_tail[dst_port]->next = (struct queued_udp_packet*)packet;
269+
udp_list_tail[dst_port] = packet;
266270
}
267-
unlock_spinlock_irq(&ctx->udp_read_lock, flags);
271+
unlock_spinlock_irq(&udp_read_lock, flags);
268272
}
269273

270274
void udpwrite_statement(struct basic_ctx* ctx) {
@@ -340,23 +344,23 @@ char* basic_udpread(struct basic_ctx* ctx) {
340344
}
341345
memset(&ctx->last_packet, 0, sizeof(ctx->last_packet));
342346
uint64_t flags;
343-
lock_spinlock_irq(&ctx->udp_read_lock, &flags);
344-
queued_udp_packet* queue = ctx->udp_packets[port];
347+
lock_spinlock_irq(&udp_read_lock, &flags);
348+
queued_udp_packet* queue = udp_packets[port];
345349
if (queue) {
346350
ctx->last_packet = *queue;
347-
if (queue == ctx->udp_list_tail[port]) {
351+
if (queue == udp_list_tail[port]) {
348352
/* This packet is the tail packet */
349-
ctx->udp_list_tail[port] = (queued_udp_packet *)ctx->udp_list_tail[port]->prev;
350-
if (ctx->udp_list_tail[port]) {
351-
ctx->udp_list_tail[port]->next = NULL;
353+
udp_list_tail[port] = (queued_udp_packet *)udp_list_tail[port]->prev;
354+
if (udp_list_tail[port]) {
355+
udp_list_tail[port]->next = NULL;
352356
}
353357
}
354-
ctx->udp_packets[port] = (queued_udp_packet *)queue->next;
355-
if (ctx->udp_packets[port]) {
356-
ctx->udp_packets[port]->prev = NULL;
358+
udp_packets[port] = (queued_udp_packet *)queue->next;
359+
if (udp_packets[port]) {
360+
udp_packets[port]->prev = NULL;
357361
}
358362
buddy_free(ctx->allocator, queue);
359363
}
360-
unlock_spinlock_irq(&ctx->udp_read_lock, flags);
364+
unlock_spinlock_irq(&udp_read_lock, flags);
361365
return ctx->last_packet.data ? (char*)ctx->last_packet.data : "";
362366
}

0 commit comments

Comments
 (0)