ref: edaac09f58050103fe7cb60b23aabc423155a210
parent: bec856ac010318bc911e62d729088f0b6e4b8441
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat May 17 20:24:08 EDT 2025
io: add bitmask argument
--- a/sys/man/1/io
+++ b/sys/man/1/io
@@ -16,6 +16,8 @@
.I address
[
.I value
+] [
+.I mask
]
.SH DESCRIPTION
.I io
@@ -25,6 +27,18 @@
or
.B -w
for reading or writing, respectively.
+When a
+.I mask
+is provided for a read,
+it is applied with a logical
+.B AND
+operation to the value.
+When a
+.I mask
+is provided for a write,
+the set bits in the mask select the bits from
+.I value
+to be modified.
The default operation size is a byte.
C style notation for integers (e.g.
.B 0x42
@@ -31,9 +45,10 @@
or
.BR 023 )
is accepted for the
-.I address
-and
+.IR address ,
.I value
+and
+.I mask
parameters.
.PP
.TP
--- a/sys/src/cmd/io.c
+++ b/sys/src/cmd/io.c
@@ -7,7 +7,7 @@
void
usage(void)
{
- fprint(2, "%s: [-f file] [ -WLME ] [-r | -w] address [ value ]\n", argv0);
+ fprint(2, "%s: [-f file] [ -WLME ] [-r | -w] address [ value ] [ mask ]\n", argv0);
exits("usage");
}
@@ -15,10 +15,10 @@
main(int argc, char** argv) {
int fd, size, op;
ulong port;
- uvlong data;
+ uvlong data, value, mask;
uchar datab[8];
- data = 0;
+ data = value = mask = 0;
size = 1;
op = -1;
ARGBEGIN {
@@ -33,14 +33,39 @@
} ARGEND;
if(op == -1) usage();
if(argc < 1) usage();
- if(op == OWRITE && argc < 2) usage();
- port = strtoul(argv[0], 0, 0);
- if(op == OWRITE) data = strtoull(argv[1], 0, 0);
-
+ port = strtoul(*argv, 0, 0);
+ argv++, argc--;
+ if(op == OWRITE) {
+ if(argc < 1) usage();
+ value = strtoull(*argv, 0, 0);
+ argv++, argc--;
+ }
+ if(argc > 0){
+ mask = ~strtoull(*argv, 0, 0);
+ argv++, argc--;
+ if(op == OWRITE){
+ op = ORDWR;
+ value &= ~mask;
+ }
+ }
+ if(op == OREAD)
+ mask = ~mask;
+ USED(argv);
+ if(argc != 0) usage();
fd = open(file==nil?datac[size]:file, op);
if(fd == -1) sysfatal("open: %r");
-
- if(op == OWRITE) {
+ if(op == OREAD || op == ORDWR) {
+ memset(datab, 0, 8);
+ if(pread(fd, datab, size, port) != size)
+ sysfatal("pread: %r");
+ data = datab[0] | (datab[1] << 8) | (datab[2] << 16) |
+ (datab[3] << 24) | ((uvlong)datab[4] << 32) |
+ ((uvlong)datab[5] << 40) | ((uvlong)datab[6] << 48) |
+ ((uvlong)datab[7] << 56);
+ data &= mask;
+ }
+ if(op == OWRITE || op == ORDWR) {
+ data |= value;
datab[0] = data;
datab[1] = data >> 8;
datab[2] = data >> 16;
@@ -52,15 +77,6 @@
if(pwrite(fd, datab, size, port) != size)
sysfatal("pwrite: %r");
}
- else {
- memset(datab, 0, 8);
- if(pread(fd, datab, size, port) != size)
- sysfatal("pread: %r");
- data = datab[0] | (datab[1] << 8) | (datab[2] << 16) |
- (datab[3] << 24) | ((vlong)datab[4] << 32) |
- ((vlong)datab[5] << 40) | ((vlong)datab[6] << 48) |
- ((vlong)datab[7] << 56);
- print("0x%ullx\n", data);
- }
+ print("0x%ullx\n", data);
exits(nil);
}
--
⑨