Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
schierlm committed May 23, 2022
0 parents commit 6a674d6
Show file tree
Hide file tree
Showing 11 changed files with 1,428 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cos-lite-old.tal
collapseos.bin
*.rom
blkfs
blk0*
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "collapseos"]
path = collapseos
url = https://github.com/schierlm/collapseos
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# collapseos-uxn

Port of CollapseOS to uxn Tal

## Description

This is a port of [Collapse OS](http://collapseos.org/) (Snapshot 2022-05-09) to the
[uxn](https://100r.co/site/uxn.html)/[varvara](https://wiki.xxiivv.com/site/varvara.html)
virtual machine.

Unlike other Collapse OS ports, it does not try to assemble the whole rom image
using Collapse OS Forth. Instead it uses a two-step approach.

The core image of the OS is assambled using [uxntal](https://wiki.xxiivv.com/site/uxntal.html),
and will dynamically load a forth image from `collapseos.bin` at `$0800`, overwriting the
initialization code that resided at that place previously. As uxntal is self-hosting on UXN,
this shortcut was deemed acceptable to me. The tooling for uxntal in VS Code as well as UXN32
debugger support made porting definitely faster for me that way. Also, the ISA/ABI is unstable
enough to require three different uxnasm builds to compile for three different emulators, so
building an assembler written in Forth is just not an option for me.

Also note that the port was started at the CVM port and only implements the bare minimum
of native words - first make it work, then make it faster.

I was considering to use the native operand and return stack for the Forth operand and return
stack, but ultimately decided against it. The event-driven nature of keyboard input would
have required the `(key)` word to unwind the stack and store it elsewhere, and later restore
once a key is pressed or the timer interrupt vector fires.

Therefore, like most other ports, the Forth operand and return stack live in normal system memory;
the stack pointers live in the zero page among other global variables.

There are two versions. The normal version supports a block filesystem which may either exist as
a single file named `blkfs`, or multiple files named `blk0000` to `blk9999`. At first startup
the former file is converted to the latter form and then deleted. This design choice was driven
by the fact that when *writing* files on varvara, there is no way to seek. Therefore writing each
block into a separate file gets away with that limitation easily.

The second, *lite* version does not support block filesystems, and does not require filesystem
access. To use, you have to concatenate the forth image file to the core image file (which is `$0700`
bytes long, making the forth image end up at `$0800`).

It has been tested in the latest version of the UXN32 emulator (2022-04-26).
There is also a version of the lite image available, which is built with an older
version of uxnasm ([commit 8d14b4bbc6f1e50f313293ba301268fbc7d9090e](https://git.sr.ht/~rabbits/uxn/commit/8d14b4bbc6f1e50f313293ba301268fbc7d9090e),
to be precise), which should work in the [WebUxn](https://aduros.com/webuxn/) emulator.

## Download

Have a look in the file release section if you want to download binaries to try.

## License

GPL3, just like Collapse OS

## Moving forward

Feel free to adopt this project if you find it interesting. I will follow Virgil's route and not update this project regularly.
(The fact that there are different incompatible versions of uxn images, without even a version number for them, and some emulators
get updated and some do not, has deterred me from keeping this up to date.)
1 change: 1 addition & 0 deletions collapseos
Submodule collapseos added at 1752bf
112 changes: 112 additions & 0 deletions collapseos.tal
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
~common.tal

@blkinit ( initialize blkfs )
#00 .File/append DEO
#0400 .File/addr(length) DEO2
RTN

@blkfile "blk &startpos "000 &endpos "0 00

@setblkname ( stack: blkno )
;blkfile/endpos SWP2 ( stack: charpos number )
&nameloop
#000a DIV2k SWP2 OVR2 MUL2 ROT2 SWP2 SUB2 #0030 ADD2 ROT2
( stack: number/10 number%10+'0' charpos )
STAk SWP2 POP2
DUP2 ;blkfile/startpos NEQ2 #77 ROT2 ROT2 #0001 SUB2 SWP2 ROT2 POP
( stack: charpos-1 number/10 cond )
,&nameloop JCN POP2 POP2 ( stack empty )
RTN

@op-uxnStorage
;ppop JSR2 ;ppop JSR2 ;ppop JSR2 .ZP/tmp1 STZ2 ( tmp1 = block number ) .ZP/tmp2 STZ2 ( tmp2 = memory address )
SWP POP DUP #01 EQU ,&read JCN
#02 EQU ,&write JCN
;handler/stop JMP2
&read POP
.ZP/tmp1 LDZ2 ;setblkname JSR2
;blkfile .File/addr(name) DEO2
.ZP/tmp2 LDZ2 .File/addr(read) DEO2
;handler/next JMP2
&write
.ZP/tmp1 LDZ2 ;setblkname JSR2
;blkfile .File/addr(name) DEO2
.ZP/tmp2 LDZ2 .File/addr(write) DEO2
;handler/next JMP2

|0800 @ROMSTART

( ### initialization code - will be overwritten by ROM file ### )

( variables used by initialization program )
@infile "blkfs 00
@romfile "collapseos.bin 00

@init
#0000 .ZP/tmp1 STZ2 ( tmp1 = offset )
&copyfile ( copy blkfs to individual files )
( read block )
;infile .File/addr(name) DEO2
#0400 .File/addr(length) DEO2
.ZP/tmp1 LDZ2 ( stack: offs )
&readloop
;COPYBUF .File/addr(read) DEO2
DUP2 #0001 SUB2 SWP2 ( stack: offs-1 offs )
#0000 NEQ2 ,&readloop JCN POP2 ( stack empty )
.File/success DEI2 #0000 EQU2 ,&done JCN ( quit if EOF reached )
( now we need to update the file name )
.ZP/tmp1 LDZ2 ;setblkname JSR2
( write block )
;blkfile .File/addr(name) DEO2
#00 .File/append DEO
#0400 .File/addr(length) DEO2
;COPYBUF .File/addr(write) DEO2
.ZP/tmp1 LDZ2 INC2 .ZP/tmp1 STZ2
;&copyfile JMP2
&done
;infile .File/addr(name) DEO2
#01 .File/delete DEO
( initialize zero page )
PS_ADDR .ZP/psp STZ2
RS_ADDR .ZP/rsp STZ2
#ffff .ZP/ir STZ2
;ROMSTART .ZP/pc STZ2
#00 .KBuf/read STZ
#00 .KBuf/write STZ
#00 .KBuf/altgr-flag STZ
#00 .ZP/curX STZ
#00 .ZP/curY STZ
( initialize theme )
#0f0f .System/r DEO2
#0f0f .System/g DEO2
#0ff0 .System/b DEO2
( initialize and clear screen )
#0290 .Screen/width DEO2
#00d8 .Screen/height DEO2
.EmptySprite #00
&clearloop ADDk #00 SWP STZ INC DUP #08 LTH ,&clearloop JCN
ADD #fe SWP STZ
;EmptySprite .Screen/addr DEO2
#00 #00 ( stack: y x )
&lineloop
OVR INC #00 SWP #0008 MUL2 .Screen/y DEO2
&cellloop
DUP INC #00 SWP #0008 MUL2 .Screen/x DEO2
#49 .Screen/sprite DEO
INC DUP #50 LTH ,&cellloop JCN
POP INC #00 OVR #19 LTH ,&lineloop JCN
POP2
( prepare to read ROM )
;romfile .File/addr(name) DEO2
#2000 .File/addr(length) DEO2
;ROMSTART .File/addr(read)

( go to main program )
;main JMP2

( copy buffer )
|0a00 @COPYBUF $1

( file device )
|a0 @File [ &vector $2 &success $2 &addr(stat) $2 &delete $1 &append $1
&addr(name) $2 &addr(length) $2 &addr(read) $2 &addr(write) $2 ]
Loading

0 comments on commit 6a674d6

Please sign in to comment.