/
52-plot-pixel.asm
139 lines (119 loc) · 4.7 KB
/
52-plot-pixel.asm
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
; Example that is used in following article:
; Vývoj her a dem pro ZX Spectrum: vlastní vykreslovací subrutiny potřetí
; https://www.root.cz/clanky/vyvoj-pro-zx-spectrum-vlastni-vykreslovaci-subrutiny-potreti/
;
; This article is part of series:
; "Vývoj pro slavné ZX Spectrum"
; https://www.root.cz/serialy/vyvoj-pro-slavne-zx-spectrum/
;
; Repository:
; https://github.com/tisnik/8bit-fame
;
; Example #52:
; Drawing real pixel, but erasing whole 8x1 pixel block background.
;
; This source code is available at:
; https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/52-plot-pixel.asm
SCREEN_ADR equ $4000
CHAR_ADR equ $3c00
ENTRY_POINT equ $8000
org ENTRY_POINT
; Vstupní bod celého programu
start:
ld b, 0 ; x-ová souřadnice vykreslovaného pixelu
ld c, 0 ; y-ová souřadnice vykreslovaného pixelu
loop:
call plot ; vykreslení pixelu
call delay
inc b ; posun na další souřadnici
inc c
ld a, b
cp 192 ; test na ukončení smyčky
jr nz, loop ; opakovat, dokud není vykreslena celá šikmá "úsečka"
finito:
jr finito ; ukončit program nekonečnou smyčkou
delay:
; zpožďovací rutina
; nemění žádné registry
push bc ; uschovat hodnoty registrů, které se používají ve smyčkách
ld b, 20 ; počitadlo vnější zpožďovací smyčky
outer_loop:
ld c, 0 ; počitadlo vnitřní zpožďovací smyčky
inner_loop:
dec c ; snížení hodnoty počitadla (v první iteraci 256->255)
jr NZ, inner_loop ; opakovat, dokud není dosaženo nuly
djnz outer_loop ; opakovat vnější smyčku, nyní s počitadlem v B
pop bc ; obnovit hodnoty registrů změněných smyčkami
ret ; návrat z podprogramu
plot:
; druhá varianta podprogramu pro vykreslení pixelu
;
; parametry:
; B - x-ová souřadnice (v pixelech)
; C - y-ová souřadnice (v pixelech)
call calc_pixel_address ; výpočet adresy pixelu
call calc_pixel_value ; výpočet ukládané hodnoty
ld (hl), a ; zápis hodnoty pixelu
ret ; návrat z podprogramu
calc_pixel_value:
; parametry:
; B - x-ová souřadnice (v pixelech)
;
; návratové hodnoty:
; A - hodnota pixelu
push bc ; zapamatovat si hodnotu v registru B
ld a, b ; A: X7 X6 X5 X4 X3 X2 X1 X0
and %00000111 ; A: 0 0 0 0 0 X2 X1 X0
jr z, put_1 ; pokud je nyní souřadnice nulová, zapíšeme výchozí masku + konec
ld b, a ; počitadlo smyčky
ld a, %10000000 ; výchozí maska
next_shift:
srl a ; posunout masku doprava
djnz next_shift ; 1x až 7x
pop bc ; obnovit hodnotu v registru B
ret ; návrat z podprogramu
put_1:
ld a, %10000000 ; výchozí maska je současně i návratovou hodnotou
pop bc ; obnovit hodnotu v registru B
ret ; návrat z podprogramu
calc_pixel_address:
; parametry:
; B - x-ová souřadnice (v pixelech)
; C - y-ová souřadnice (v pixelech)
;
; návratové hodnoty:
; HL - adresa pro zápis pixelu
;
; pozměněné registry:
; A
;
; vzor adresy:
; 0 1 0 Y7 Y6 Y2 Y1 Y0 | Y5 Y4 Y3 X4 X3 X2 X1 X0
ld a, c ; všech osm bitů Y-ové souřadnice
and %00000111 ; pouze spodní tři bity y-ové souřadnice (Y2 Y1 Y0)
; A: 0 0 0 0 0 Y2 Y1 Y0
or %01000000 ; "posun" do obrazové paměti (na 0x4000)
ld h, a ; část horního bajtu adresy je vypočtena
; H: 0 1 0 0 0 Y2 Y1 Y0
ld a, c ; všech osm bitů Y-ové souřadnice
rra
rra
rra ; rotace doprava -> Y1 Y0 xx Y7 Y6 Y5 Y4 Y3
and %00011000 ; zamaskovat
; A: 0 0 0 Y7 Y6 0 0 0
or h ; a přidat k vypočtenému mezivýsledku
ld h, a ; H: 0 1 0 Y7 Y6 Y2 Y1 Y0
ld a, c ; všech osm bitů Y-ové souřadnice
rla
rla ; A: Y5 Y4 Y3 Y2 Y1 Y0 xx xx
and %11100000 ; A: Y5 Y4 Y3 0 0 0 0 0
ld l, a ; část spodního bajtu adresy je vypočtena
ld a, b ; všech osm bitů X-ové souřadnice
rra
rra
rra ; rotace doprava -> 0 0 0 X7 X6 X5 X4
and %00011111 ; A: 0 0 0 X7 X6 X5 X4 X3
or l ; A: Y5 Y3 Y3 X7 X6 X5 X4 X3
ld l, a ; spodní bajt adresy je vypočten
ret ; návrat z podprogramu
end ENTRY_POINT