1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
# z80count
This is a simple tool that parses Z80 assembler using regular expressions (I know!)
and adds comments to the code with the cycles used by the instruction.
It needs testing and probably a proper Z80 parser, but it works for me and the
Z80 assembler syntax I use.
<img src="https://git.usebox.net/z80count/plain/etc/demo-vim.gif" alt="demo" style="width:800px;">
## Install
`z80count` requires Python 3.
To install for production you can use `pip`:
pip3 install --user z80count
Or you can download the package from [z80count's refs tab](https://git.usebox.net/z80count/refs/), unpack and run:
python3 setup.py install
To install for development run:
git clone https://git.usebox.net/z80count
cd z80count
pip3 install -e ".[dev]"
## Usage
You can use it with:
z80count < file.asm > file_c.asm
Or inside `vim` you can:
:% !z80count -s
With `-s` the tool adds a subtotal.
By default `z80count` will try to update comments replacing existing annotations.
Comments added by `z80count` are aligned to the column given in the `-c`
(`--column`) option (50 by default). By default the comments are aligned using
spaces, if you prefer tabs instead use the `-t` option. In order to compute the
padding `z80count` assumes that a `TAB` equals 8 spaces. Use the
option `-T` to override this.
Example:
```asm
push hl
pop bc
ld hl, $5800
ld e, 7
.fade_out_all_loop0
push hl
push bc
halt
.fade_out_all_loop1
ld a, (hl)
and 7
jr z, no_fade_all_ink
dec a
.no_fade_all_ink
ld d, a
ld a, (hl)
and $38
jr z, no_fade_all_paper
sub 8
.no_fade_all_paper
or d
ld d, a
ld a, (hl)
and $c0
or d
ld (hl), a
inc hl
dec bc
ld a, b
or c
jr nz, fade_out_all_loop1
pop bc
pop hl
dec e
jr nz, fade_out_all_loop0
```
Processed with `z80count.py -s` results in:
```asm
push hl ; [11 .. 11]
pop bc ; [10 .. 21]
ld hl, $5800 ; [10 .. 31]
ld e, 7 ; [7 .. 38]
.fade_out_all_loop0
push hl ; [11 .. 49]
push bc ; [11 .. 60]
halt ; [4 .. 64]
.fade_out_all_loop1
ld a, (hl) ; [7 .. 71]
and 7 ; [7 .. 78]
jr z, no_fade_all_ink ; [12/7 .. 90/85]
dec a ; [4 .. 89]
.no_fade_all_ink
ld d, a ; [4 .. 93]
ld a, (hl) ; [7 .. 100]
and $38 ; [7 .. 107]
jr z, no_fade_all_paper ; [12/7 .. 119/114]
sub 8 ; [7 .. 121]
.no_fade_all_paper
or d ; [4 .. 125]
ld d, a ; [4 .. 129]
ld a, (hl) ; [7 .. 136]
and $c0 ; [7 .. 143]
or d ; [4 .. 147]
ld (hl), a ; [7 .. 154]
inc hl ; [6 .. 160]
dec bc ; [6 .. 166]
ld a, b ; [4 .. 170]
or c ; [4 .. 174]
jr nz, fade_out_all_loop1 ; [12/7 .. 186/181]
pop bc ; [10 .. 191]
pop hl ; [10 .. 201]
dec e ; [4 .. 205]
jr nz, fade_out_all_loop0 ; [12/7 .. 217/212]
```
Comments show subtotals, and there are two types:
- `[A .. T0]`
- `[B/A .. T1/T0]`
Where A, B, T0 and T1 are:
- A is the number of cycles of current instruction. In case of a conditional
instruction, this is the value when the condition is not met.
- B is the number of cycles of current instruction when the condition is met.
- T0 is the subtotal when the conditional is not met.
- T1 is the subtotal when the conditional is met.
## Config file
`z80count` will look for a config file in the following places, in order:
- the file given in the environment variable `Z80COUNT_RC`.
- a file `z80countrc` in the directory given in the environment variable
`XDG_DEFAULT_HOME` or, if this variable is undefined or empty, in
the directory `~/.config`.
- a file `.z80countrc` in the home directory.
Example:
```
[z80count]
# Column to align newly added comments
# column = 50
# Enable debug (show the matched case)
# debug = no
# Include subtotals
# subtotals = no
# Number of spaces for each tab
# tab width = 8
# Keep previous cycle annotations in the comment
# keep cycles = no
# Use tabs to align newly added comments instead of spaces
# use tabs = yes
```
## Editor support
- [z80count-el](https://github.com/patxoca/z80count-el), emacs
## Troubleshooting
Here be dragons!
Use `-d` flag if you think one instruction is not correctly parsed.
Feel free to open a PR if you find a bug!
## Authors
- Juan J. Martinez <jjm@usebox.net>
- Alexis Roda https://github.com/patxoca
|