<commit_before># z80DotNet, A Simple .Net-Based Z80 Cross-Assembler
### Version 1.4
## Introduction

The z80DotNet Macro Assembler is a simple cross-assembler targeting the Zilog Z80 and compatible CPU. It is written for .Net (Version 4.5.1) and supports all of the published (legal) instructions of the Z80 processor, as well as most of the unpublished (illegal) operations. Like the MOS 6502, the Z80 was a popular choice for video game system and microcomputer manufacturers in the 1970s and mid-1980s. For more information, see [wiki entry](https://en.wikipedia.org/wiki/Zilog_Z80) or [Z80 resource page](http://www.z80.info/) to learn more about this microprocessor.

## Legal
* z80DotNet (c) 2017 informedcitizenry
* Mathos Parser, a [math expression parser](https://mathosparser.codeplex.com/) (c) 2012 <NAME>
* System.CommandLine, a [command-line argument parser](https://github.com/dotnet/corefxlab/tree/master/src/System.CommandLine) (c) Microsoft Corporation

See LICENSE and LICENSE_third_party for licensing information.
## Overview
The z80DotNet assembler is simple to use. Invoke it from a command line with the assembly source and (optionally) the output filename in the parameters. For instance, a `/z80DotNet myprg.asm` command will output assembly listing in `myprgm.asm` to binary output. To specify output file name use the `-o <file>` or `--output=<file>` option, otherwise the default output filename will be `a.out`.

You can specify as many source files as assembly input as needed. For instance, `/z80DotNet mylib.asm myprg.asm` will assemble both the `mylib.asm` and `myprgm.asm` files sequentially to output. Be aware that if both files define the same symbol an assembler error will result.
## General Features
### Numeric constants
Integral constants can be expressed as decimal, hexadecimal, and binary. Decimal numbers are written as is, while hex numbers are prefixed with a `$` and binary numbers are prefixed with a `%`.
```
            65490 = 65490
            $ffd2 = 65490
%1111111111010010 = 65490
```
Negative numbers are assembled according to two's complement rules, with the highest bits set. Binary strings can alternatively be expressed as `.` for `0` and `#` for `1`, which is helpful for laying out pixel data:
```
    number1     .byte %...###..
                .byte %..####..
                .byte %.#####..
                .byte %...###..
                .byte %...###..
                .byte %...###..
                .byte %...###..
                .byte %.#######
```                
## Labels and Symbols
When writing assembly, hand-coding branches, addresses and constants can be time-consuming and lead to errors. Labels take care of this work for you! There is no restriction on name size, but all labels must begin with an underscore or letter, and can only contain underscores, letters, and digits, and they cannot be re-assigned:
```
            yellow   =   6

            ld  a,yellow     ; load yellow into acc.
            jr  nz,setborder ; now set the border color
            ...
setborder:  call $229b       ; poke border color with acc.
```
Trailing colons for jump instructions are optional.

Using the `.block`/`.endblock` directives, labels can be placed in scope blocks to avoid the problem of label reduplication:
```
            ...
endloop     ld  a,$ff    
            ret

myblock     .block
            call endloop    ; accumulator will be 0
            ...             ; since endloop is local to myblock
endloop     xor a
            ret
            .endblock
```
Labels inside named scopes can be referenced with dot notation:
```
speccy     .block

key_in      = $10a8
wait_key    = $15d4

            .endblock

            call speccy.key_in  ; call the subroutine whose label        
                                ; is defined in the speccy block
```
Blocks can also be nested. Labels in unnamed blocks are only visible in their own block, and are unavailable outside:
```
            .block
            call inc32
            ...
inc32       inc bc
            jr  z,done
            inc de
done        ret
            .endblock

            call inc32  ; will produce an assembler error
```
Anonymous labels allow one to do away with the need to think of unique label names altogether. There are two types of anonymous labels: forward and backward. Forward anonymous labels are declared with a `+`, while backward anonymous labels are declared using a `-`. They are forward or backward to the current assembly line and are referenced in the operand with one or more `+` or `-` symbols:
```
-               ld  a,(ix+$00)
                jr  nz,+            ; jump to first forward anonymous from here
                ld  a,' '
+               rst $10
                inc ix
                rlca
                jr  nc,-            ; jump to first backward anonymous from here
                add a,a
                jr  nc,+            ; jump to first forward anonymous from here
                and %01111111
                jr  ++              ; jump to second forward anonymous from here
+               ld  (ix+$10),a
                ret
+               ld  (ix+$20),a
                ret
```
As you can see, anonymous labels, though convenient, would hinder readability if used too liberally. They are best for small branch jumps, though can be used in the same was as labels:
```
-               .byte $01, $02, $03
                ld  a,(-)           ; best to put anonymous label reference inside paranetheses.
```
### Comments
Adding comments to source promotes readability, particularly in assembly. Comments can be added to source code in one of two ways, as single-line trailing source code, or as a block. Single-line comments start with a semi-colon. Any text written after the semi-colon is ignored, unless it is being expressed as a string or constant character.
```
    lda #0      ; 0 = color black
    sta $d020   ; set border color to accumulator
    lda #';'    ; the first semi-colon is a char literal so will be assembled
    jsr $ffd2   
```
Block comments span multiple lines, enclosed in `.comment` and `.endcomment` directives. These are useful when you want to exclude unwanted code:
```
    .comment

    this will set the cpu on fire do not assemble!

    lda #$ff
    sta $5231

    .endcomment
```
## Non-code (data) assembly
In addition to z80 assembly, data can also be assembled. Expressions evaluate internally as 64-bit signed integers, but **must** fit to match the expected operand size; if the value given in the expression exceeds the data size, this will cause an illegal quantity error. The following pseudo-ops are available:

| Directive | Size                      |
| --------- | ------------------------- |
| `.byte`   | One byte unsigned         |
| `.sbyte`  | One byte signed           |
| `.addr`   | Two byte address          |
| `.sint`   | Two bytes signed          |
| `.word`   | Two bytes unsigned        |
| `.rta`    | Two byte return address   |
| `.lint`   | Three bytes signed        |
| `.long`   | Three bytes unsigned      |
| `.dint`   | Four bytes signed         |
| `.dword`  | Four bytes unsigned       |
| `.align`  | Zero or more bytes        |
| `.fill`   | One or more bytes         |   

Multi-byte directives assemble in little-endian order (the least significant byte first), which conforms to the 6502 architecture. Data is comma-separated, and each value can be a constant or expression:
```
sprite      .byte %......##,%########,%##......
jump        .word sub1, sub2, sub3, sub4
```
For `.fill` and `.align`, the assembler accepts either one or two arguments. The first is the quantity, while the second is the value. If the second is not given then it is assumed to be uninitialized data (see below). For `.fill`, quantity is number of bytes, for `.align` it is the number of bytes by which the program counter can be divided with no remainder:
```
unused      .fill 256,0 ; Assemble 256 bytes with the value 0

atpage      .align 256  ; The program counter is guaranteed to be at a page boundary
```
Sometimes it is desirable to direct the assembler to make a label reference an address, but without outputting bytes at that address. For instance, program variables. Use the `?` symbol instead of an expression:
```
highscore   .dword ?    ; set the symbol highscore to the program counter,
                        ; but do not output any bytes
```                             
Note that if uninitialized data is defined, but thereafter initialized data is defined, the output will fill bytes to the program counter from the occurrence of the uninitialized symbol:
```
highscore   .dword ?    ; uninitialized highscore variables
            xor a,a     ; The output is now 6 bytes in size
```
### Text processing and encoding
In addition to integral values, 6502.Net can assemble Unicode text. Text strings are enclosed in double quotes, character literals in single quotes. Escaped double quotes are not recognized, so embedded quotation marks must be "broken out" as separate operands:
```
"He said, ",'"',"How are you?",'"'
```<commit_msg>Update README.md [ci skip]<commit_after># z80DotNet, A Simple .Net-Based Z80 Cross-Assembler
### Version 1.4
## Introduction

The z80DotNet Macro Assembler is a simple cross-assembler targeting the Zilog Z80 and compatible CPU. It is written for .Net (Version 4.5.1) and supports all of the published (legal) instructions of the Z80 processor, as well as most of the unpublished (illegal) operations. Like the MOS 6502, the Z80 was a popular choice for video game system and microcomputer manufacturers in the 1970s and mid-1980s. For more information, see [wiki entry](https://en.wikipedia.org/wiki/Zilog_Z80) or [Z80 resource page](http://www.z80.info/) to learn more about this microprocessor.

## Legal
* z80DotNet (c) 2017 informedcitizenry
* Mathos Parser, a [math expression parser](https://mathosparser.codeplex.com/) (c) 2012 <NAME>
* System.CommandLine, a [command-line argument parser](https://github.com/dotnet/corefxlab/tree/master/src/System.CommandLine) (c) Microsoft Corporation

See LICENSE and LICENSE_third_party for licensing information.
## Overview
The z80DotNet assembler is simple to use. Invoke it from a command line with the assembly source and (optionally) the output filename in the parameters. For instance, a `/z80DotNet myprg.asm` command will output assembly listing in `myprgm.asm` to binary output. To specify output file name use the `-o <file>` or `--output=<file>` option, otherwise the default output filename will be `a.out`.

You can specify as many source files as assembly input as needed. For instance, `/z80DotNet mylib.asm myprg.asm` will assemble both the `mylib.asm` and `myprgm.asm` files sequentially to output. Be aware that if both files define the same symbol an assembler error will result.
## General Features
### Numeric constants
Integral constants can be expressed as decimal, hexadecimal, and binary. Decimal numbers are written as is, while hex numbers are prefixed with a `$` and binary numbers are prefixed with a `%`.
```
            65490 = 65490
            $ffd2 = 65490
%1111111111010010 = 65490
```
Negative numbers are assembled according to two's complement rules, with the highest bits set. Binary strings can alternatively be expressed as `.` for `0` and `#` for `1`, which is helpful for laying out pixel data:
```
    number1     .byte %...###..
                .byte %..####..
                .byte %.#####..
                .byte %...###..
                .byte %...###..
                .byte %...###..
                .byte %...###..
                .byte %.#######
```                
## Labels and Symbols
When writing assembly, hand-coding branches, addresses and constants can be time-consuming and lead to errors. Labels take care of this work for you! There is no restriction on name size, but all labels must begin with an underscore or letter, and can only contain underscores, letters, and digits, and they cannot be re-assigned:
```
            yellow   =   6

            ld  a,yellow     ; load yellow into acc.
            jr  nz,setborder ; now set the border color
            ...
setborder:  call $229b       ; poke border color with acc.
```
Trailing colons for jump instructions are optional.

Using the `.block`/`.endblock` directives, labels can be placed in scope blocks to avoid the problem of label reduplication:
```
            ...
endloop     ld  a,$ff    
            ret

myblock     .block
            call endloop    ; accumulator will be 0
            ...             ; since endloop is local to myblock
endloop     xor a
            ret
            .endblock
```
Labels inside named scopes can be referenced with dot notation:
```
speccy     .block

key_in      = $10a8
wait_key    = $15d4

            .endblock

            call speccy.key_in  ; call the subroutine whose label        
                                ; is defined in the speccy block
```
Blocks can also be nested. Labels in unnamed blocks are only visible in their own block, and are unavailable outside:
```
            .block
            call inc32
            ...
inc32       inc bc
            jr  z,done
            inc de
done        ret
            .endblock

            call inc32  ; will produce an assembler error
```
Anonymous labels allow one to do away with the need to think of unique label names altogether. There are two types of anonymous labels: forward and backward. Forward anonymous labels are declared with a `+`, while backward anonymous labels are declared using a `-`. They are forward or backward to the current assembly line and are referenced in the operand with one or more `+` or `-` symbols:
```
-               ld  a,(ix+$00)
                jr  nz,+            ; jump to first forward anonymous from here
                ld  a,' '
+               rst $10
                inc ix
                rlca
                jr  nc,-            ; jump to first backward anonymous from here
                add a,a
                jr  nc,+            ; jump to first forward anonymous from here
                and %01111111
                jr  ++              ; jump to second forward anonymous from here
+               ld  (ix+$10),a
                ret
+               ld  (ix+$20),a
                ret
```
As you can see, anonymous labels, though convenient, would hinder readability if used too liberally. They are best for small branch jumps, though can be used in the same was as labels:
```
-               .byte $01, $02, $03
                ld  a,(-)           ; best to put anonymous label reference inside paranetheses.
```
### Comments
Adding comments to source promotes readability, particularly in assembly. Comments can be added to source code in one of two ways, as single-line trailing source code, or as a block. Single-line comments start with a semi-colon. Any text written after the semi-colon is ignored, unless it is being expressed as a string or constant character.
```
    lda #0      ; 0 = color black
    sta $d020   ; set border color to accumulator
    lda #';'    ; the first semi-colon is a char literal so will be assembled
    jsr $ffd2   
```
Block comments span multiple lines, enclosed in `.comment` and `.endcomment` directives. These are useful when you want to exclude unwanted code:
```
    .comment

    this will set the cpu on fire do not assemble!

    lda #$ff
    sta $5231

    .endcomment
```
## Non-code (data) assembly
In addition to z80 assembly, data can also be assembled. Expressions evaluate internally as 64-bit signed integers, but **must** fit to match the expected operand size; if the value given in the expression exceeds the data size, this will cause an illegal quantity error. The following pseudo-ops are available:

| Directive | Size                      |
| --------- | ------------------------- |
| `.byte`   | One byte unsigned         |
| `.sbyte`  | One byte signed           |
| `.addr`   | Two byte address          |
| `.sint`   | Two bytes signed          |
| `.word`   | Two bytes unsigned        |
| `.rta`    | Two byte return address   |
| `.lint`   | Three bytes signed        |
| `.long`   | Three bytes unsigned      |
| `.dint`   | Four bytes signed         |
| `.dword`  | Four bytes unsigned       |
| `.align`  | Zero or more bytes        |
| `.fill`   | One or more bytes         |   

Multi-byte directives assemble in little-endian order (the least significant byte first), which conforms to the z80 architecture. Data is comma-separated, and each value can be a constant or expression:
```
sprite      .byte %......##,%########,%##......
jump        .word sub1, sub2, sub3, sub4
```
For `.fill` and `.align`, the assembler accepts either one or two arguments. The first is the quantity, while the second is the value. If the second is not given then it is assumed to be uninitialized data (see below). For `.fill`, quantity is number of bytes, for `.align` it is the number of bytes by which the program counter can be divided with no remainder:
```
unused      .fill 256,0 ; Assemble 256 bytes with the value 0

atpage      .align 256  ; The program counter is guaranteed to be at a page boundary
```
Sometimes it is desirable to direct the assembler to make a label reference an address, but without outputting bytes at that address. For instance, program variables. Use the `?` symbol instead of an expression:
```
highscore   .dword ?    ; set the symbol highscore to the program counter,
                        ; but do not output any bytes
```                             
Note that if uninitialized data is defined, but thereafter initialized data is defined, the output will fill bytes to the program counter from the occurrence of the uninitialized symbol:
```
highscore   .dword ?    ; uninitialized highscore variables
            xor a,a     ; The output is now 6 bytes in size
```
### Text processing and encoding
In addition to integral values, z80DotNet can assemble Unicode text. Text strings are enclosed in double quotes, character literals in single quotes. Escaped double quotes are not recognized, so embedded quotation marks must be "broken out" as separate operands:
```
"He said, ",'"',"How are you?",'"'
```
{'fraction_non_alphanumeric': 0.08592251630226314, 'fraction_numerical': 0.018192777686448572, 'mean_word_length': 2.3959806475623373, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1387451', 'n_tokens_mistral': 5098, 'n_tokens_neox': 4619, 'n_words': 2323}