mirror of
https://github.com/KarolS/millfork.git
synced 2025-08-07 12:25:40 +00:00
Update documentation
This commit is contained in:
@@ -14,7 +14,7 @@ even up to hardware damage.
|
|||||||
|
|
||||||
* stray pointers: indexing a pointer that doesn't point to a valid object or indexing it past the end of the pointed object leads to undefined behaviour
|
* stray pointers: indexing a pointer that doesn't point to a valid object or indexing it past the end of the pointed object leads to undefined behaviour
|
||||||
|
|
||||||
* reading uninitialized variables: will return undefined values
|
* reading uninitialized variables: will return undefined values and, if the type is `bool`, may put the program in an invalid state
|
||||||
|
|
||||||
* reading variables used by return dispatch statements but not assigned a value: will return undefined values
|
* reading variables used by return dispatch statements but not assigned a value: will return undefined values
|
||||||
|
|
||||||
@@ -41,4 +41,8 @@ Currently, such functions may be evaluated either once or twice. This might be f
|
|||||||
|
|
||||||
* jumping across the scope of for loop that uses a fixed list or across functions
|
* jumping across the scope of for loop that uses a fixed list or across functions
|
||||||
|
|
||||||
|
* division by zero and modulo by zero
|
||||||
|
|
||||||
|
* decimal addition and subtraction of values that are not binary-coded decimals
|
||||||
|
|
||||||
The above list is not exhaustive.
|
The above list is not exhaustive.
|
||||||
|
@@ -76,6 +76,7 @@ Since various assemblers use different mnemonics for undocumented opcodes,
|
|||||||
Millfork supports multiple mnemonics per opcode. The default one is given first:
|
Millfork supports multiple mnemonics per opcode. The default one is given first:
|
||||||
|
|
||||||
Intel syntax | Zilog syntax
|
Intel syntax | Zilog syntax
|
||||||
|
----|----
|
||||||
**DSUB** | **DSUB**
|
**DSUB** | **DSUB**
|
||||||
**ARHL**, RRHL | **SRA HL**
|
**ARHL**, RRHL | **SRA HL**
|
||||||
**RLDE**, RDEL | **RL DE**
|
**RLDE**, RDEL | **RL DE**
|
||||||
|
@@ -10,6 +10,14 @@ Syntax:
|
|||||||
|
|
||||||
`[segment (<segment>)] asm <return_type> <name> ( <params> ) @ <address> extern`
|
`[segment (<segment>)] asm <return_type> <name> ( <params> ) @ <address> extern`
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
void do_nothing() { }
|
||||||
|
inline byte two() = 2
|
||||||
|
extern asm void chkout(byte a) @ $FFD2
|
||||||
|
segment(prgrom0) void main_loop(word w, byte x) align(fast) { // body omitted
|
||||||
|
|
||||||
|
|
||||||
* `<segment>`: segment name; if absent, then defaults to `default_code_segment` as defined for the platform (usually `default`)
|
* `<segment>`: segment name; if absent, then defaults to `default_code_segment` as defined for the platform (usually `default`)
|
||||||
|
|
||||||
* `<modifiers>`: zero or more of the following:
|
* `<modifiers>`: zero or more of the following:
|
||||||
|
@@ -48,6 +48,9 @@ Every encoding is guaranteed to support at least
|
|||||||
`{q}` for double quote
|
`{q}` for double quote
|
||||||
and `{apos}` for single quote/apostrophe.
|
and `{apos}` for single quote/apostrophe.
|
||||||
|
|
||||||
|
The number of bytes used to represent given characters may differ from the number of the characters.
|
||||||
|
For example, the `petjp`, `msx_jp` and `jis` encodings represent ポ as two separate characters, and therefore two bytes.
|
||||||
|
|
||||||
For the list of all text encodings and escape sequences, see [this page](./text.md).
|
For the list of all text encodings and escape sequences, see [this page](./text.md).
|
||||||
|
|
||||||
In some encodings, multiple characters are mapped to the same byte value,
|
In some encodings, multiple characters are mapped to the same byte value,
|
||||||
@@ -80,8 +83,15 @@ Character literals are surrounded by single quotes and optionally followed by th
|
|||||||
'x' ascii
|
'x' ascii
|
||||||
'W'
|
'W'
|
||||||
|
|
||||||
|
Character literals have to be separated from preceding operators with whitespace:
|
||||||
|
|
||||||
|
a='a' // wrong
|
||||||
|
a = 'a' // ok
|
||||||
|
|
||||||
From the type system point of view, they are constants of type byte.
|
From the type system point of view, they are constants of type byte.
|
||||||
|
|
||||||
|
If the character cannot be represented as one byte, an error is raised.
|
||||||
|
|
||||||
For the list of all text encodings and escape sequences, see [this page](./text.md).
|
For the list of all text encodings and escape sequences, see [this page](./text.md).
|
||||||
|
|
||||||
If the characters in the literal cannot be encoded in particular encoding, an error is raised.
|
If the characters in the literal cannot be encoded in particular encoding, an error is raised.
|
||||||
|
@@ -240,11 +240,14 @@ an access to the element of the array `a` at the location assigned to the key `i
|
|||||||
|
|
||||||
* otherwise: a compile error
|
* otherwise: a compile error
|
||||||
|
|
||||||
Note that you cannot access a whole array element if it's bigger than 2 bytes, but you can access its fields or take its pointer:
|
Note that you cannot access a whole array element if it's bigger than 2 bytes (except in a simple assignment),
|
||||||
|
but you can access its fields or take its pointer:
|
||||||
|
|
||||||
array(int32) a[6]
|
array(int32) a[6]
|
||||||
|
|
||||||
a[2] // not ok
|
a[2] // not ok
|
||||||
|
a[2] = 4 // ok, assignments are an exception
|
||||||
|
x = a[2] // ok, assignments are an exception
|
||||||
a[2].b0 // ok
|
a[2].b0 // ok
|
||||||
a[2].loword // ok
|
a[2].loword // ok
|
||||||
a[2].pointer // ok
|
a[2].pointer // ok
|
||||||
|
@@ -22,6 +22,13 @@ Syntax:
|
|||||||
|
|
||||||
`[segment(<segment>)] [volatile] [<storage>] <type> <name> [@<address>] [= <initial_value>]`
|
`[segment(<segment>)] [volatile] [<storage>] <type> <name> [@<address>] [= <initial_value>]`
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
byte a
|
||||||
|
volatile byte thing @ $D000
|
||||||
|
int24 x = 7
|
||||||
|
segment(s1) word w
|
||||||
|
|
||||||
* `<segment>`: segment name; if absent, then defaults to `default`.
|
* `<segment>`: segment name; if absent, then defaults to `default`.
|
||||||
|
|
||||||
* `volatile` means that the variable is volatile.
|
* `volatile` means that the variable is volatile.
|
||||||
@@ -74,6 +81,10 @@ For every variable `x` larger than a byte, extra subvariables are defined:
|
|||||||
|
|
||||||
`const <type> <name> = <value>`
|
`const <type> <name> = <value>`
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
const byte two = 2
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
### Alias definitions
|
### Alias definitions
|
||||||
@@ -104,7 +115,7 @@ This allows for overriding definitions of library functions by another library:
|
|||||||
void f() {}
|
void f() {}
|
||||||
void g() {}
|
void g() {}
|
||||||
alias f = g!
|
alias f = g!
|
||||||
// now the original f is removed and all calls to f will call g instead
|
// the original f is removed and all calls to f will call g instead
|
||||||
|
|
||||||
### Array declarations
|
### Array declarations
|
||||||
|
|
||||||
@@ -118,6 +129,16 @@ Syntax:
|
|||||||
|
|
||||||
`[segment(<segment>)] [const] array [(<element type>)] <name> [[<size>]] [align ( <alignment> )] [@<address>] [= <initial_values>]`
|
`[segment(<segment>)] [const] array [(<element type>)] <name> [[<size>]] [align ( <alignment> )] [@<address>] [= <initial_values>]`
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
array results[8]
|
||||||
|
array(word) words = [1,2,500]
|
||||||
|
array page [256] align(256)
|
||||||
|
segment(chrrom) const array graphics @ $0000 = file("tiles.chr")
|
||||||
|
array(byte) identity = [for i,0,until,256 [i]]
|
||||||
|
array text = "hello world"z
|
||||||
|
const array(room) rooms = [room(1,2), room(3,5)]
|
||||||
|
|
||||||
* `<segment>`: segment name; if absent,
|
* `<segment>`: segment name; if absent,
|
||||||
then defaults to `default_code_segment` as defined for the platform if the array has initial values,
|
then defaults to `default_code_segment` as defined for the platform if the array has initial values,
|
||||||
or to `default` if it doesn't.
|
or to `default` if it doesn't.
|
||||||
@@ -203,6 +224,8 @@ All starting modules are considered to be imported by all source files explicitl
|
|||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
See also [the operator reference](./operators.md)
|
||||||
|
|
||||||
### `if` statement
|
### `if` statement
|
||||||
|
|
||||||
Syntax:
|
Syntax:
|
||||||
@@ -374,6 +397,12 @@ continue do
|
|||||||
continue <variable>
|
continue <variable>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Labelless `break` and `continue` apply to the innermost `for`, `while` or `do-while` loop.
|
||||||
|
|
||||||
|
`break for`, `continue do` etc. apply to the innermost loop of the given type.
|
||||||
|
|
||||||
|
`break i` and `continue i` apply to the innermost `for` loop that uses the `i` variable.
|
||||||
|
|
||||||
### `goto` and `label`
|
### `goto` and `label`
|
||||||
|
|
||||||
Syntax:
|
Syntax:
|
||||||
@@ -388,7 +417,7 @@ Such labels are only visible in the scope of the local function.
|
|||||||
|
|
||||||
The `goto` expression jumps to the pointer value of the expression.
|
The `goto` expression jumps to the pointer value of the expression.
|
||||||
|
|
||||||
Jumping using `goto` across the scope of for loop that uses a fixed list or across functions is not allowed.
|
Jumping using `goto` across the scope of `for` loop that uses a fixed list or across functions is not allowed.
|
||||||
|
|
||||||
Computed gotos are supported:
|
Computed gotos are supported:
|
||||||
|
|
||||||
|
@@ -49,6 +49,10 @@ and `petscr` for strings you're copying to screen memory directly.
|
|||||||
|
|
||||||
### Escape sequences
|
### Escape sequences
|
||||||
|
|
||||||
|
Escape sequences allow for including characters in the string literals that would be otherwise impossible to type.
|
||||||
|
|
||||||
|
Some escape sequences may expand to multiple characters. For example, in several encodings `{n}` expands to `{x0D}{x0A}`.
|
||||||
|
|
||||||
##### Available everywhere
|
##### Available everywhere
|
||||||
|
|
||||||
* `{q}` – double quote symbol
|
* `{q}` – double quote symbol
|
||||||
|
@@ -99,9 +99,44 @@ The value of the pointer `f.pointer` may not be the same as the value of the fun
|
|||||||
|
|
||||||
## Boolean types
|
## Boolean types
|
||||||
|
|
||||||
TODO
|
Boolean types can be used as conditions. They have two possible values, `true` and `false`, although
|
||||||
|
|
||||||
* `bool` – a 1-byte boolean value
|
* `bool` – a 1-byte boolean value. An uninitialized variable of type `bool` may contain an invalid value.
|
||||||
|
|
||||||
|
* several boolean types based on the CPU flags that may be used only as a return type for a function written in assembly:
|
||||||
|
|
||||||
|
true if flag set | true if flag clear | 6502 flag | 8080 flag | Z80 flag | LR35902 flag
|
||||||
|
-----------------|--------------------|-----------|-----------|----------|-------------
|
||||||
|
`set_carry` | `clear_carry` | C | C | C | C
|
||||||
|
`set_zero` | `clear_zero` | Z | Z | Z | Z
|
||||||
|
`set_overflow` | `clear_overflow` | V | P¹ | P/V | _n/a_²
|
||||||
|
`set_negative` | `clear_negative` | N | S | S | _n/a_²
|
||||||
|
|
||||||
|
1\. 8080 does not have a dedicated overflow flag, so since Z80 reuses the P flag for overflow,
|
||||||
|
8080 uses the same type names for compatibility.
|
||||||
|
|
||||||
|
2\. LR35902 does not support these types due to the lack of appropriate flags
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
bool f() = true
|
||||||
|
|
||||||
|
void do_thing(bool b) {
|
||||||
|
if b { do_one_thing() }
|
||||||
|
else { do_another_thing() }
|
||||||
|
}
|
||||||
|
|
||||||
|
asm set_carry always_true() {
|
||||||
|
#if ARCH_6502
|
||||||
|
SEC
|
||||||
|
? RTS
|
||||||
|
#elseif ARCH_I80
|
||||||
|
SCF
|
||||||
|
? RET
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
## Special types
|
## Special types
|
||||||
|
|
||||||
|
@@ -24,13 +24,15 @@ Support for other devices using supported processors can be easily added, usuall
|
|||||||
|
|
||||||
### What microprocessors are supported?
|
### What microprocessors are supported?
|
||||||
|
|
||||||
* 6502 and its descendants: 6510, 65C02, Ricoh 2A03, and to a lesser degree CSG 65CE02, Hudson Soft HuC6280 and WDC 65816. 6509 is not supported and will not be.
|
* MOS 6502 and its descendants: 6510, 65C02, Ricoh 2A03, and to a lesser degree CSG 65CE02, Hudson Soft HuC6280 and WDC 65816. 6509 is not supported and will not be.
|
||||||
|
|
||||||
* Intel 8080, Intel 8085, Zilog Z80, Sharp LR35902 (also known as GBZ80)
|
* Intel 8080, Intel 8085, Zilog Z80, Sharp LR35902 (also known as GBZ80)
|
||||||
|
|
||||||
* There is also partial experimental support for Intel 8086, via automatic 8080-to-8086 translation.
|
* There is also partial experimental support for Intel 8086, via automatic 8080-to-8086 translation.
|
||||||
The generated code is very large and very slow.
|
The generated code is very large and very slow.
|
||||||
|
|
||||||
|
* Support for Motorola 6809 is coming in the future.
|
||||||
|
|
||||||
### Why Millfork when I can use assembly?
|
### Why Millfork when I can use assembly?
|
||||||
|
|
||||||
* Assembly will not be portable. If you want to target both 6502 and Z80, you'd have to maintain two separate codebases.
|
* Assembly will not be portable. If you want to target both 6502 and Z80, you'd have to maintain two separate codebases.
|
||||||
|
Reference in New Issue
Block a user