# Dusk Tour

The idea of a Dusk tutorial is a bit weird because if you don't know your way
around Forth and Dusk, you won't be able to make good use of it. Therefore,
if you want to begin using Dusk, you should learn about it using the serious
path, which begins at [doc/operator] followed by [doc/usage].

However, if what you want is to have an idea of Dusk's capabilities without
having to invest time learning about Forth and Dusk semantics too much, then
this tour walks you through a couple of interesting places. All you need to do
is to type the commands.

Explanations are minimal, because it's useless to understand what you're typing
if you don't have a good understanding of Dusks's underpinnings. See this tour
more like a show and tell.

If something doesn't work as expected during the tour, check if you're running
it from a release tag (example "v11") or from the master branch. This tour is
checked for correctness before releases but not after each commit.

## Requirements

To run this tour, you need a Dusk with graphical capabilities. The "sdl" flavor
of Usermode Dusk fits the bill, but this tour will work on any Dusk with a
video framebuffer. The "curses" flavor will also work for a while, until we
get to the "graphics" part of the tour.

What will *not* work are the POSIX VM "./dusk" or the "stream" flavor
"./usermode/dusk". You need "./usermode/dusk-sdl" or "./usermode/dusk-curses" or
an appropriate hardware port of Dusk OS such as the Raspberry Pi port.

## Let's go

  Dusk OS
  137KB used 31MB free ok

That's the welcome prompt. Dusk is waiting for a command. Typing on the keyboard
will make letters appear on the screen. Execution of the typed line only happens
when you press Return. Backspace can be used to erase characters.

So what's those 31MB free? It's your system memory. It's a contiguous area of
memory and "here" is where you're "currently at" in it. Where is that? Let's
find out:

  here .x
  f5c7480a ok

That's your playground. Any address within "here" and 31MB is good to play with.
Let's dump what we have in front of us:

  here dump
  :f5c7480a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7481a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7482a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7483a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7484a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7485a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7486a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7487a 0000 0000 0000 0000 0000 0000 0000 0000 ................

What a nice bunch of zeroed out bits. What about those 137KB used? What do they
look like?

  here $100 - dump
  :f5c7470a 8906 b83a 0000 00e8 16fc fdff 83c6 fc89 ...:............
  :f5c7471a 068b 4424 0483 c6fc 8906 e83f 14fe ffe8 ..D$.......?....
  :f5c7472a 26fc fdff 83c6 fc89 06b8 0800 0000 83c0 &...............
  :f5c7473a 0150 ad83 0424 ff0f 8432 0000 008b 5c24 .P...$...2....\$
  :f5c7474a 08ba 0200 0000 0154 2408 83c6 fc89 060f .......T$.......
  :f5c7475a b643 0183 c6fc 8906 0fb6 03e8 ae13 feff .C..............
  :f5c7476a e8a9 13fe ffe8 e0fb fdff e9c4 ffff ff83 ................
  :f5c7477a c404 8944 2404 ad83 c6fc 8906 b810 0000 ...D$...........

Ok. You can play with that memory. For example, write to it:

  $cafebabe here !
   ok
  here @ .x
  cafebabe ok
  here dump
  :f5c7480a beba feca 0000 0000 0000 0000 0000 0000 ................
  :f5c7481a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7482a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7483a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7484a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7485a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7486a 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c7487a 0000 0000 0000 0000 0000 0000 0000 0000 ................

As you can see, that's a little endian system. In fact, I'm going to tell you,
this is a i386 system. How about we flex our assembler muscles?

  needs asm/i386
  code add42 ax 42 i) add, ret,
  5 add42 .
  47 ok

ALTERNATE REALITY: if you run the tour on a system that isn't i386, "add42" will
crash your system. What you can do, however, is to use the HAL, which will
assemble the same thing in your native architecture:

  code add42 42 i) +, exit,
  5 add42 . \ works on any CPU
  47 ok

What we did here is that we created a new native word, right "here". Let's look
at what's in "add42".

  ' add42 dump
  :f5c77e48 052a 0000 00c3 0000 0000 0000 0000 0000 .*..............
  :f5c77e58 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c77e68 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c77e78 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c77e88 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c77e98 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c77ea8 0000 0000 0000 0000 0000 0000 0000 0000 ................
  :f5c77eb8 0000 0000 0000 0000 0000 0000 0000 0000 ................

Keen eyes among you will recognize i386 binary format. But we aren't all nerdy
weirdos, right? Let's use a disassembler.

  needs asm/i386d
  ' add42 dis
  f5c77e48 ADD  EAX,0000002a 05 2a 00 00 00
  f5c77e4d RET               c3
  f5c77e4e ADD  {EAX},AL     00 00
  f5c77e50 MOV  ESP,00f5c780 bc 80 c7 f5 00
  f5c77e55 ADD  AL,{EAX}     02 00
  f5c77e57 ADD  {EAX},AL     00 00
  f5c77e59 OR   {EAX},AL     08 00
  f5c77e5b ADD  {EAX+d0f5c5c8},DH
    00 b0 c8 c5 f5 d0
  f5c77e61 ENTR              c8
  f5c77e62 LDS               c5
  f5c77e63 CMC               f5
  f5c77e64 Jc   L,f5c77e61   7c fb
  f5c77e66 LDS               c5
  f5c77e67 CMC               f5
  f5c77e68 INT               cd
  f5c77e69 SBB  AL,{EAX}     1a 00

Only the first two lines, until the RET, are relevant. The rest is non-code
garbage because the disassembler can't know when to stop disassembling, so it
spits a pre-defined number of lines.

That's pretty much what we've assembled right? Of course it is.

What about compiling some C code now? We could do it through the command line,
but it will be more fun to use the editor.

  needs text/ged
  0 "foo.c" bootfs newfile
  edload<< foo.c
  ged

At that point, you have a blank screen. That's the editor. To add a line, press
the key 'o'. The cursor will go at the bottom of the screen, at which point to
can type the line to add. Pressing return will add the line. You can move around
with keys h/j/k/l. If you make a mistake, you can delete the current line by
pressing ':' followed by the command "1 dl". More information about the editor
can be found at [text/ged]. Try to end up with that contents:

  int add54(int n) {
    return n+54;
  }

When you have that, press "q" to quit the editor and return to the command line,
then save your work:

  edsave
  Saving edbuf to foo.c ok

Alright! Now let's compile that.

  needs comp/c/cc
  cc<< foo.c
  5 add54 .

Good stuff. What does it look like, code wise?

  ' add54 dis
  f5c8a284 ADD  ESI,fc       83 c6 fc
  f5c8a287 MOV  [ESI],EAX    89 06
  f5c8a289 MOV  EAX,[ESI]    8b 06
  f5c8a28b ADD  EAX,36       83 c0 36
  f5c8a28e ADD  ESI,04       83 c6 04
  f5c8a291 RET               c3
  f5c8a292 ADD  {EAX},AL     00 00
  f5c8a294 ADD  {EAX},AL     00 00
  f5c8a296 ADD  {EAX},AL     00 00
  f5c8a298 ADD  {EAX},AL     00 00
  f5c8a29a ADD  {EAX},AL     00 00
  f5c8a29c ADD  {EAX},AL     00 00
  f5c8a29e ADD  {EAX},AL     00 00
  f5c8a2a0 ADD  {EAX},AL     00 00
  f5c8a2a2 ADD  {EAX},AL     00 00
  f5c8a2a4 ADD  {EAX},AL     00 00

A bit looser than the straight assembler version, but not that bad heh?

## Graphics

From that point on, we need graphical capabilities. usermode/dusk-sdl gives you
that, but other Dusk port can give it to you too. If you have a blue 8x8 square
that moves around with the mouse, you're good.

  100 100 screen pixdst! 255 0 0 >rgb565 60 80 fillpixels

This should show a 60x80 pixels red square on the screen. Yes, this code above
needs to be typed on a single line. Why? Press "return" a few times. See how the
console overwrites the red square? That's because the concept of "screen" is as
simple as it sounds: a framebuffer plugged to the screen. When you draw to it,
you do it directly. Refreshingly simple right? Yes, but it's a shared resource
that the console also uses. Whenever a character is drawn to the screen, it is
using the same [gr/pix] API, which has global states. Therefore, your draw
operation need to happen without the console drawing a character in between.

Dusk doesn't have a vector drawing API yet, so drawing is mostly about moving
pixels around, but that doesn't mean we can't have fun with that. It has a
sprite based API in [gr/varvara] and we can test that it works with:

  needs gr/varvara
  vscreentest

This should draw a rectangle along with a few hearts and diamonds here and
there. This shows you that the varvara screen system works. At the heart of this
API is the concept of sprite, which is a 8x8 bitmap, which can have 2 or 4
colors. Let's look at an example sprite:

  heart 16 cspit[]
  00 66 ff ff ff 7e 3c 18 00 00 00 18 18 00 00 00 ok

The "heart" array comes from gr/varvara and is the sprite we use for our little
test we've just drawn. Each byte represents a 8 pixels row, with each bit
representing a pixel, b7 being leftmost and b0 being rightmost. The first 8
bytes are the first color channel and the following 8 bytes are the second color
channel. Therefore, a 1bpp sprite is 8 bytes long and a 2bpp sprite is 16 bytes
long and its first 8 bytes is the same as a 1bpp sprite.

So, hum, what kind of fun could we have with this. Let's draw a whole bunch of
those hearts.

  10 to X 10 to Y heart to sprite
  1 2bpp) X+) 10 times) drawsprite
  refreshscreen

You should see 10 hearts being drawn in a vertical line (why vertical when we
use X+)? see [gr/varvara] for details). We don't need to type everything in a
single line because this unit uses a separate buffer, which we draw to screen
using "refreshscreen". What about a horizontal line of flipped hearts using
another color blend?

  2 2bpp) Y+) flipY) 12 times) drawsprite
  refreshscreen

Wait, I just had an idea. What about this blue cursor we move around with the
mouse. Is that a pixbuf? Can I play with it? Of course you can!

  vpalette heart mapicn 0 0 cursor pixdst! drawpmap

Tadaa! your mouse cursor is now a heart!

So that's it for the Dusk Tour, with the hopes that it titillated your thirst
for power. This power doesn't come for free though. Significant effort have to
be invested in learning Forth, then Dusk. You can begin at [doc/usage].
