1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-02 08:30:55 +11:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Virgil Dupras
d3dbeb450f Tidy up 2020-05-03 12:54:22 -04:00
Virgil Dupras
47a9c89f19 Update READMEs 2020-05-03 12:51:21 -04:00
Virgil Dupras
5504c796ee tools: add blkup
With this tool, we can send content to a TRS-80 directly to floppy.
This paves the way to writing ourselves a set of disks containing the
blkfs!
2020-05-03 08:53:17 -04:00
Virgil Dupras
7344186c62 tools: add blkup
not actually tested yet...
2020-05-03 07:32:19 -04:00
10 changed files with 116 additions and 112 deletions

1
.gitignore vendored
View File

@ -1,2 +1 @@
*.o *.o
/kernel/user.h

View File

@ -27,33 +27,25 @@ github issue][forth-issue].
Documentation is lacking, it's not ready yet, this is a WIP branch. Documentation is lacking, it's not ready yet, this is a WIP branch.
## See it in action ## Getting started
Michael Schierl has put together [a set of emulators running in the browser that Usage documentation is in-system, so access to documentation requires you to
run Collapse OS in different contexts][jsemul]. run Collapse OS. Fortunately, doing so in an emulator is easy.
Using those while following along with the [User Guide](doc/) is your quickest
path to giving Collapse OS a try.
## Documentation
Usage documentation is in-system. Run `0 LIST` for an introduction. You can
also open `blk/000` in a modern text editor.
See `/emul/README.md` for getting an emulated system running. See `/emul/README.md` for getting an emulated system running.
Then, run `0 LIST` for an introduction, follow instructions from there.
## Organisation of this repository ## Organisation of this repository
* `forth`: Forth is slowly taking over this project (see issue #4). It comes * `blk`: Collapse OS filesystem's content. That's actually where Collapse OS'
from this folder. source code is located. Everything else is peripheral.
* `recipes`: collection of recipes that assemble parts together on a specific * `recipes`: collection of recipes that assemble Collapse OS on a specific
machine. machine.
* `blk`: Collapse OS filesystem's content. See `000` for intro.
* `doc`: User guide for when you've successfully installed Collapse OS.
* `tools`: Tools for working with Collapse OS from "modern" environments. For * `tools`: Tools for working with Collapse OS from "modern" environments. For
example, tools for facilitating data upload to a Collapse OS machine example, tools for facilitating data upload to a Collapse OS machine
through a serial port. through a serial port.
* `emul`: Emulated applications. * `emul`: Tools for running Collapse OS in an emulated environment.
* `tests`: Automated test suite for the whole project. * `tests`: Automated test suite for the whole project.
## Status ## Status
@ -63,13 +55,13 @@ for more information.
## Discussion ## Discussion
For a general discussion of Collapse OS and the ecosystem of technologies and ideas that may develop around it refer to [r/collapseos][discussion] For a general discussion of Collapse OS and the ecosystem of technologies and
ideas that may develop around it refer to [r/collapseos][discussion]
A more traditional [mailing list][listserv] and IRC (#collapseos on freenode) channels are also maintained. A more traditional [mailing list][listserv] and IRC (#collapseos on freenode)
channels are also maintained.
[libz80]: https://github.com/ggambetta/libz80
[web]: https://collapseos.org [web]: https://collapseos.org
[jsemul]: https://schierlm.github.io/CollapseOS-Web-Emulator/
[discussion]: https://www.reddit.com/r/collapseos [discussion]: https://www.reddit.com/r/collapseos
[listserv]: http://lists.sonic.net/mailman/listinfo/collapseos [listserv]: http://lists.sonic.net/mailman/listinfo/collapseos
[forth-issue]: https://github.com/hsoft/collapseos/issues/4 [forth-issue]: https://github.com/hsoft/collapseos/issues/4

View File

@ -1,51 +0,0 @@
This file describe tricks and conventions that are used throughout the code and
might need explanation.
*** Quickies
or a: Equivalent to "cp 0", but results in a shorter opcode.
xor a: sets A to 0 more efficiently than ld a, 0
and 0xbf: Given a letter in the a-z range, changes it to its uppercase value
if it's already uppercased, then it stays that way.
*** Z flag for results
Z if almost always used as a success indicator for routines. Set for success,
Reset for failure. "xor a" (destroys A) and "cp a" (preserves A) are used to
ensure Z is set. To ensure that it is reset, it's a bit more complicated and
"unsetZ" routine exists for that, although that in certain circumstances,
"inc a \ dec a" or "or a" can work.
*** Little endian
z80 is little endian in its 16-bit loading operations. For example, "ld hl, (0)"
will load the contents of memory address 0 in L and memory address 1 in H. This
little-endianess is followed by Collapse OS in most situations. When it's not,
it's specified in comments.
This get a bit awkward with regards to 32-bit. There are no "native" z80 32-bit
operations, so z80 doesn't mandate an alignment. In Collapse OS, 32-bit numbers
are stored as "big endian pair of little endian 16-bit numbers". For example,
if "ld dehl, (0)" existed and if the first 4 bytes of memory were 0x01, 0x02,
0x03 and 0x04, then DE (being the "high" word) would be 0x0201 and HL would be
0x0403.
*** DAA
When it comes to dealing with decimals, the DAA instruction, which look a bit
obscur, can be very useful. It transforms the result of a previous arithmetic
operation involving two BCD (binary coded decimal, one digit in high nibble,
the other digit in low nibble. For example, 0x99 represents 99) into a valid
BCD. For example, 0x12+0x19=0x2b, but after calling DAA, it will be 0x31.
To clear misunderstanding: this does **not** transform an arbitrary value into
BCD. For example, "ld a, 0xff \ daa" isn't going to magically give you a binary
coded 255 (how could it?). This is designed to be ran after an arithmetic
operation.
A common trick to transform an arbitrary number to BCD is to loop 8 times over
your bitstream, SLA your bits out of your binary value and then run
"adc a, a \ daa" over it (with provisions for carries if you expect numbers
over 99).

View File

@ -6,7 +6,7 @@ emulator.
## Not real hardware ## Not real hardware
In the few emulated apps described below, we don't try to emulate real hardware In the few emulated apps described below, we don't try to emulate real hardware
because the goal here is to facilitate userspace development. because the goal here is to facilitate "high level" development.
These apps run on imaginary hardware and use many cheats to simplify I/Os. These apps run on imaginary hardware and use many cheats to simplify I/Os.
@ -18,44 +18,17 @@ folder.
First, make sure that the `libz80` git submodule is checked out. If not, run First, make sure that the `libz80` git submodule is checked out. If not, run
`git submodule init && git submodule update`. `git submodule init && git submodule update`.
After that, you can run `make` and it builds all applications. After that, you can run `make` and it builds the `forth` interpreter.
## forth Run `./forth` to get the COllapse OS prompt. Type `0 LIST` for help.
Collapse OS' Forth interpreter, which is in the process of replacing the
zasm-based project.
The Forth interpreter is entirely self-hosting, that is, it assembles its
binary with itself.
There are 3 build stages.
**Stage 0**: At this stage, all we have are our bootstrap binaries, `boot.bin`
and `z80c.bin`. We concatenate them into `forth0.bin` ans then wrap the
emulator around it which is named `stage1` (because it builds the stage 1) to
have a barebone forth interpreter.
**Stage 1**: The `stage1` binary allows us to augment `forth0.bin` with
the compiled dictionary of a full Forth interpreter. We feed it with
`$(FORTHSRCS)` and then dump the resulting compiled dict.
From there, we can create `forth1.bin`, which is wrapped by both the `forth`
and `stage2` executables. `forth` is the interpreter you'll use.
**Stage 2**: `stage2` is used to resolve the chicken-and-egg problem and use
the power of a full Forth intepreter, including an assembler, to assemble
`z80c.bin`. This is a manual step executed through `make updatebootstrap`.
Normally, running this step should yield the exact same `boot.bin` and
`z80c.bin` as before, unless of course you've changed the source.
## Problems? ## Problems?
If the libz80-wrapped zasm executable works badly (hangs, spew garbage, etc.), If the libz80-wrapped zasm executable works badly (hangs, spew garbage, etc.),
it's probably because you've broken your bootstrap binaries. They're easy to it's probably because you've broken your bootstrap binaries. They're easy to
mistakenly break. To verify if you've done that, look at your git status. If mistakenly break. To verify if you've done that, look at your git status. If
`boot.bin` or `z80c.bin` are modified, try resetting them and then run `forth.bin` is modified, try resetting it and then run `make clean all`. Things
`make clean all`. Things should go better afterwards. should go better afterwards.
If that doesn't work, there's also the nuclear option of `git reset --hard` If that doesn't work, there's also the nuclear option of `git reset --hard`
and `git clean -fxd`. and `git clean -fxd`.
@ -63,3 +36,5 @@ and `git clean -fxd`.
If that still doesn't work, it might be because the current commit you're on If that still doesn't work, it might be because the current commit you're on
is broken, but that is rather rare: the repo on Github is plugged on Travis is broken, but that is rather rare: the repo on Github is plugged on Travis
and it checks that everything is smooth. and it checks that everything is smooth.
[libz80]: https://github.com/ggambetta/libz80

1
tools/.gitignore vendored
View File

@ -10,3 +10,4 @@
/exec /exec
/blkpack /blkpack
/blkunpack /blkunpack
/blkup

View File

@ -8,9 +8,10 @@ BIN2C_TGT = bin2c
EXEC_TGT = exec EXEC_TGT = exec
BLKPACK_TGT = blkpack BLKPACK_TGT = blkpack
BLKUNPACK_TGT = blkunpack BLKUNPACK_TGT = blkunpack
BLKUP_TGT = blkup
TARGETS = $(MEMDUMP_TGT) $(BLKDUMP_TGT) $(UPLOAD_TGT) $(FONTCOMPILE_TGT) \ TARGETS = $(MEMDUMP_TGT) $(BLKDUMP_TGT) $(UPLOAD_TGT) $(FONTCOMPILE_TGT) \
$(TTYSAFE_TGT) $(PINGPONG_TGT) \ $(TTYSAFE_TGT) $(PINGPONG_TGT) $(BIN2C_TGT) $(EXEC_TGT) $(BLKPACK_TGT) \
$(BIN2C_TGT) $(EXEC_TGT) $(BLKPACK_TGT) $(BLKUNPACK_TGT) $(BLKUNPACK_TGT) $(BLKUP_TGT)
OBJS = common.o OBJS = common.o
all: $(TARGETS) all: $(TARGETS)
@ -29,6 +30,7 @@ $(BIN2C_TGT): $(BIN2C_TGT).c
$(EXEC_TGT): $(EXEC_TGT).c $(EXEC_TGT): $(EXEC_TGT).c
$(BLKPACK_TGT): $(BLKPACK_TGT).c $(BLKPACK_TGT): $(BLKPACK_TGT).c
$(BLKUNPACK_TGT): $(BLKUNPACK_TGT).c $(BLKUNPACK_TGT): $(BLKUNPACK_TGT).c
$(BLKUP_TGT): $(BLKUP_TGT).c
$(TARGETS): $(OBJS) $(TARGETS): $(OBJS)
$(CC) $(CFLAGS) $@.c $(OBJS) -o $@ $(CC) $(CFLAGS) $@.c $(OBJS) -o $@

67
tools/blkup.c Normal file
View File

@ -0,0 +1,67 @@
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "common.h"
/* Push specified file to specified device blk device, starting from blkno
* and upwards.
*/
int main(int argc, char **argv)
{
if (argc != 4) {
fprintf(stderr, "Usage: ./blkup device blkno fname\n");
return 1;
}
unsigned int blkno = strtol(argv[2], NULL, 10);
FILE *fp = fopen(argv[3], "r");
if (!fp) {
fprintf(stderr, "Can't open %s.\n", argv[3]);
return 1;
}
int fd = open(argv[1], O_RDWR|O_NOCTTY|O_SYNC);
if (fd < 0) {
fprintf(stderr, "Could not open %s\n", argv[1]);
return 1;
}
set_interface_attribs(fd, 0, 0);
set_blocking(fd, 1);
char s[0x40];
char buf[1024] = {0};
sendcmdp(fd, ": _ 1024 0 DO KEY DUP .x I BLK( + C! LOOP ;");
int returncode = 0;
while (fread(buf, 1, 1024, fp)) {
sendcmd(fd, "_");
for (int i=0; i<1024; i++) {
putchar('.');
fflush(stdout);
write(fd, &buf[i], 1);
usleep(1000); // let it breathe
mread(fd, s, 2); // read hex pair
s[2] = 0; // null terminate
unsigned char c = strtol(s, NULL, 16);
if (c != buf[i]) {
// mismatch!
fprintf(stderr, "Mismatch at bno %d (%d) %d != %d.\n", blkno, i, buf[i], c);
// we don't exit now because we need to "consume" our whole program.
returncode = 1;
}
usleep(1000); // let it breathe
}
readprompt(fd);
if (returncode) break;
memset(buf, 0, 1024);
sprintf(s, "%d BLK> ! BLK!", blkno);
sendcmdp(fd, s);
blkno++;
}
sendcmdp(fd, "FORGET _");
printf("Done!\n");
fclose(fp);
return returncode;
}

View File

@ -16,6 +16,24 @@ void mread(int fd, char *s, int count)
} }
} }
void mexpect(int fd, char ec)
{
char c;
mread(fd, &c, 1);
if (c != ec) {
fprintf(stderr, "Expected %d but got %d\n", ec, c);
}
}
void readprompt(int fd)
{
mexpect(fd, ' ');
mexpect(fd, 'o');
mexpect(fd, 'k');
mexpect(fd, '\r');
mexpect(fd, '\n');
}
void sendcmd(int fd, char *cmd) void sendcmd(int fd, char *cmd)
{ {
char junk[2]; char junk[2];
@ -28,16 +46,16 @@ void sendcmd(int fd, char *cmd)
usleep(1000); usleep(1000);
} }
write(fd, "\r", 1); write(fd, "\r", 1);
mread(fd, junk, 2); // sends back \r\n mexpect(fd, '\r');
mexpect(fd, '\n');
usleep(1000); usleep(1000);
} }
// Send a cmd and also read the "> " prompt // Send a cmd and also read the " ok" prompt
void sendcmdp(int fd, char *cmd) void sendcmdp(int fd, char *cmd)
{ {
char junk[2];
sendcmd(fd, cmd); sendcmd(fd, cmd);
mread(fd, junk, 2); readprompt(fd);
} }
// from https://stackoverflow.com/a/6947758 // from https://stackoverflow.com/a/6947758

View File

@ -1,6 +1,7 @@
void sendcmd(int fd, char *cmd); void sendcmd(int fd, char *cmd);
void sendcmdp(int fd, char *cmd); void sendcmdp(int fd, char *cmd);
void mread(int fd, char *s, int count); void mread(int fd, char *s, int count);
void readprompt(int fd);
int set_interface_attribs(int fd, int speed, int parity); int set_interface_attribs(int fd, int speed, int parity);
void set_blocking(int fd, int should_block); void set_blocking(int fd, int should_block);

View File

@ -67,7 +67,7 @@ int main(int argc, char **argv)
} }
usleep(1000); // let it breathe usleep(1000); // let it breathe
} }
mread(fd, s, 2); // "> " prompt readprompt(fd);
sendcmdp(fd, "FORGET _"); sendcmdp(fd, "FORGET _");
printf("Done!\n"); printf("Done!\n");
fclose(fp); fclose(fp);