minor formatting for the final of {uxn tutorial day 1}

This commit is contained in:
sejo 2024-03-09 15:38:34 +01:00
parent 616b71de72
commit aafc711f17
2 changed files with 35 additions and 32 deletions

View File

@ -28,11 +28,8 @@ implement the following concepts as {coloring computers}:
## tutorial
### day 1
* check links / update links
* updating tutorial for uxntal playground
### day 2 and onwards
* remove square brackets in devices?
* recap how to use learn-uxn for the programs there
* check current color theme: Background/alpha, Selection, Foreground, Application
* update images if needed
@ -45,8 +42,9 @@ implement the following concepts as {coloring computers}:
=> https://lists.sr.ht/~rabbits/uxn/%3CCAE2DaSQQMb8XVfsn2NSsXQO+-0m2t4U2GD7nYD3GBUO4GPeTxQ%40mail.gmail.com%3E Whole auto sprite flipping
* make a folder of examples
* include uxn5 in the web tutorial so that code can be run from mthere
* include uxn5 in the web tutorial so that code can be run from there
=> https://git.sr.ht/~rabbits/uxn5 uxn5
* format and update {uxn running}
## traducción:

View File

@ -335,13 +335,14 @@ we'll look now at some features of uxntal that make writing and reading code a m
# runes, labels, macros
runes are special characters that indicate to uxnasm some pre-processing to do when assembling our programs.
runes are special characters that indicate to the assembler some pre-processing to do when assembling our programs.
## absolute pad rune
we already saw the first of them: | defines an "absolute pad", i.e. the address where the next written items will be located in memory.
we already saw the first of them: | defines an "absolute pad", i.e. the address where the next written items will be located in the main memory.
if the address is 1-byte long, it is assumed to be either an address of the i/o memory space or the zero-page.
if the address is 1-byte long, it is assumed to be an address of the i/o memory space or of the zero page.
if the address is 2-bytes long, it is assumed to be an address for the main memory.
## literal hex rune
@ -354,14 +355,14 @@ using this rune, we could re-write our first program as:
```
( hello.tal )
|0100 #68 #18 DEO
|0100 #68 #18 DEO #0a #18 DEO
```
the following would have the same behavior as the program above, but using one less byte (in the next day of the tutorial we'll see why)
the following would have the same behavior as the program above, but using two bytes less (in the next day of the tutorial we'll see why)
```
( hello.tal )
|0100 #6818 DEO
|0100 #6818 DEO #0a18 DEO
```
note that you can only use this rune to write the contents of either one or two bytes, i.e. two or four nibbles.
@ -374,7 +375,7 @@ if we just want to have a specific number in the main memory, without pushing it
this is the raw character or string rune: "
uxnasm reads the ascii character after the rune, and decodes its numerical value.
the assembler reads the ascii character after the rune, and decodes its numerical value.
using this rune, our "hello program" would look like the following:
@ -394,37 +395,35 @@ that's why we need to include a LIT instruction.
## runes for labels
even though right now we know that #18 corresponds to pushing the console write device port down onto the stack, for readability and future-proofing of our code it is a good practice to assign a set of labels that would correspond to that device and port.
even though right now we know that #18 corresponds to pushing the address (18) of the console write device port down onto the stack, for readability and future-proofing of our code it is a good practice to assign a set of labels that would correspond to that device and port.
the rune @ allows us to define labels, and the rune & allows us to define sub-labels.
for example, for the console device, the way you would see this written in uxntal programs for the varvara computer is the following:
```
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]
|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1
```
we can see an absolute pad to address 10, that assigns the following items to that address. because the address consists of one byte only, uxnasm assumes it is for the i/o memory space or the zero page.
here, we can see an absolute pad to address 10 (the console device), that assigns the following items to that address. because the address consists of one byte only, once we use the DEO instructions, uxn understands it's referring to the i/o memory space,.
then we see a label @Console: this label is assigned to address 10.
the square brackets are ignored, but included for readability.
next we have several sub-labels, indicated by the & rune, and relative pads, indicated by the $ rune. how do we read and interpret them?
next we have several sub-labels, indicated by the & rune, and relative pads, indicated by the $ rune. how do we read/interpret them?
* sublabel &vector has the same address as its parent label @Console: 10
* $2 skips two bytes (we could read this as &vector being an address to a 2-bytes long word)
* sublabel &read has the address 12
* $1 skips one byte (&read would be an address for a 1-byte long word)
* sublabel &pad has the address 13
* $5 skips the remaining bytes of the first group of 8 bytes in the device: these bytes correspond to the "inputs"
* sublabel &write has the address 18 (the one we knew already!)
* $1 skips one byte (&write would be an address for a 1-byte long word)
* sublabel &error has the address 19
* sublabel &vector has the same address as its parent label @Console: 10.
* $2 skips two bytes (we could read this as &vector being an address to a 2-bytes long word).
* sublabel &read has the address 12.
* $1 skips one byte (&read would be an address for a 1-byte long word).
* sublabel &pad has the address 13.
* $5 skips the remaining bytes of the first group of 8 bytes in the device: these bytes correspond to the "inputs".
* sublabel &write has the address 18 (the one we knew already!).
* $1 skips one byte (&write would be an address for a 1-byte long word).
* sublabel &error has the address 19.
none of this would be translated to machine code, but aids us in writing uxntal code.
the rune for referring to literal address in the zero page or i/o address space, is . (dot), and a / (slash) allows us to refer to one of its sublabels.
the rune for referring to literal addressess in the zero page or i/o address space, is . (dot), and a / (slash) allows us to refer to one of its sublabels.
remember: as a "literal address" rune it will add a LIT instruction before the corresponding address :)
@ -434,7 +433,7 @@ we could re-write our "hello program" as follows:
( hello.tal )
( devices )
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]
|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1
( main program )
|0100 LIT "h .Console/write DEO
@ -456,7 +455,7 @@ during assembly, these macros are recursively replaced by the contents in their
for example, we can see that the following piece of code is repeated many times in our program:
```
.Console/write DEO ( equivalent to #18 DEO, or LIT 18 DEO )
.Console/write DEO
```
we could define a macro called EMIT that will take from the stack a byte corresponding to a character, and print it to standard output.
@ -484,6 +483,10 @@ we can call macros inside macros, for example:
%NL { #0a EMIT } ( -- )
```
note that macros are a helpful way of grouping and reusing code, especially when beginning to learn uxntal. for more advanced uses, macros are replaced by other strategies.
for that reason, some uxntal assemblers like the one in Uxntal Playground, don't allow their use.
# a more idiomatic hello world
using all these macros and runes, our program could end up looking like the following:
@ -491,7 +494,7 @@ using all these macros and runes, our program could end up looking like the foll
```
( hello.tal )
( devices )
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]
|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1
( macros )
( print a character to standard output )
@ -528,7 +531,9 @@ EMIT EMIT EMIT EMIT EMIT
if you look at the ascii table, you'll see that the hexadecimal ascii code 30 corresponds to the digit 0, 31 to the digit 1, and so on until 39 that corresponds to digit 9.
define a PRINT-DIGIT macro that takes a number (from 0 to 9) from the stack, and prints its corresponding digit to standard output.
=> https://wiki.xxiivv.com/site/ascii.html ascii table
define a PRINT-DIGIT macro that takes a number (from 00 to 09) from the stack, and prints its corresponding digit to standard output.
```
%PRINT-DIGIT { } ( number -- )