File: mcbpm.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (237 lines) | stat: -rw-r--r-- 6,131 bytes parent folder | download | duplicates (3)
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
;
; P/M mouse callbacks for the Ataris
;
; Christian Groessler, 11.04.2014
;
; All functions in this module should be interrupt safe, because they may
; be called from an interrupt handler
;

        .include        "atari.inc"
        .importzp       sp
        .export         _mouse_pm_callbacks
        .constructor    pm_init, 27
        .destructor     pm_down

; get mouse shape data
        .import   mouse_pm_bits
        .importzp mouse_pm_height
        .importzp mouse_pm_hotspot_x
        .importzp mouse_pm_hotspot_y


; P/M definitions. The MOUSE_PM_NUM value can be changed to adjust the
; number of the P/M used for the mouse. All others depend on this value.
; Valid P/M numbers are 0 to 4. When 4 is used, the missiles are used
; as a player.
.ifdef USE_PAGE6
MOUSE_PM_NUM    = 2                             ; P/M used for the mouse
                                                ; This cannot be changed since only player #2 uses the memory at $600.
.else
MOUSE_PM_NUM    = 4                             ; P/M used for the mouse
                                                ; Using player #4 (missiles) wastes the least amount of memory on the
                                                ; atari target, since top of memory is typically at $xC20, and the
                                                ; missiles use the space at $xB00-$xBFF.
                                                ; On the atarixl target this configuration (not using page 6) is not
                                                ; really satisfying since the top of memory typically lies beneath
                                                ; the ROM and there is flickering visible while the ROM is banked in.
.endif
MOUSE_PM_BASE   = pm_base                       ; ZP location pointing to the hw area used by the selected P/M

.if MOUSE_PM_NUM = 4
MOUSE_PM_RAW    = 0                             ; MOUSE_PM_RAW is the hardware P/M number for MOUSE_PM_NUM
.macro  set_mouse_x
        ; assume CF = 0
        sta     HPOSM3
        adc     #2
        sta     HPOSM2
        adc     #2
        sta     HPOSM1
        adc     #2
        sta     HPOSM0
.endmacro
.else
MOUSE_PM_RAW    = MOUSE_PM_NUM + 1
.macro  set_mouse_x
        sta     HPOSP0 + MOUSE_PM_NUM
.endmacro
.endif

; ------------------------------------------------------------------------

        .rodata

        ; Callback structure
_mouse_pm_callbacks:
        .addr   hide
        .addr   show
        .addr   prep
        .addr   draw
        .addr   movex
        .addr   movey

; ------------------------------------------------------------------------

        .bss

omy:    .res    1                       ; old Mouse Y position
colhlp: .res    1                       ; helper variable to set P/M color

; ------------------------------------------------------------------------

        .segment "EXTZP" : zeropage

pm_base:.res    2

; ------------------------------------------------------------------------

        .code

; Hide the mouse cursor.
hide:   lda     #0
        sta     GRACTL
        rts

; Show the mouse cursor.
show:
.if MOUSE_PM_NUM < 4
        lda     #2
.else
        lda     #1
.endif
        sta     GRACTL
        jmp     update_colors

prep:
draw:
        rts

; Move the mouse cursor x position to the value in A/X.
movex:  cpx     #1
        ror     a
        clc
        adc     #48
        sbc     #(mouse_pm_hotspot_x - 1) & $FF
        set_mouse_x
        jmp     update_colors

; Move the mouse cursor y position to the value in A/X.
movey:  clc
        adc     #32
        sbc     #(mouse_pm_hotspot_y - 1) & $FF
        pha
        lda     omy
        jsr     clr_pm                  ; remove player at old position
        jsr     update_colors
        pla
        sta     omy
        ;jmp    set_pm                  ; put player to new position
        ; fall thru

; Set P/M data from 'mouse_pm_bits'
set_pm: tay
        ldx     #0
set_l:  lda     mouse_pm_bits,x
        sta     (MOUSE_PM_BASE),y
        inx
        iny
        beq     set_end
        cpx     #mouse_pm_height
        bcc     set_l
set_end:rts

; Clear (zero) P/M data
clr_pm: ldx     #mouse_pm_height
        tay
        lda     #0
clr_l:  sta     (MOUSE_PM_BASE),y
        iny
        beq     clr_end
        dex
        bne     clr_l
clr_end:rts


pm_down = hide


; this assumes a GRAPHICS 0 screen
update_colors:
        lda     COLOR2                  ; get background color
        and     #$F0
        sta     colhlp
        lda     COLOR1
        and     #$0F
        ora     colhlp

.if MOUSE_PM_NUM = 4
        sta     PCOLR0
        sta     PCOLR1
        sta     PCOLR2
        sta     PCOLR3
        lda     #0
        sta     SIZEM
.else
        sta     PCOLR0 + MOUSE_PM_NUM
        lda     #0
        sta     SIZEP0 + MOUSE_PM_NUM
.endif
        rts

; ------------------------------------------------------------------------

        .segment "ONCE"

pm_init:
        lda     #0

.ifdef USE_PAGE6

        sta     MOUSE_PM_BASE
        ldx     #6                      ; page 6
        stx     MOUSE_PM_BASE+1

.else

; use top of memory and lower sp accordingly
        sta     sp
        sta     MOUSE_PM_BASE
        lda     sp+1
        and     #7                      ; offset within 2K
        cmp     #3 + MOUSE_PM_RAW + 1   ; can we use it?
        bcc     @decr                   ; no

        lda     sp+1
        and     #$F8
@set:   adc     #3 + MOUSE_PM_RAW - 1   ; CF is set, so adding MOUSE_PM_RAW + 3
        sta     MOUSE_PM_BASE+1
        sta     sp+1
        bne     @cont                   ; jump always

@decr:  lda     sp+1
        and     #$F8
        sbc     #8 - 1                  ; CF is clear, subtracts 8
        bcs     @set                    ; jump always

@cont:  lda     #0

.endif

        tay
@iniloo:sta     (MOUSE_PM_BASE),y
        iny
        bne     @iniloo

.ifndef USE_PAGE6
        lda     MOUSE_PM_BASE+1
        and     #$F8
.endif
        sta     PMBASE

        lda     #62
        sta     SDMCTL

        lda     #1
        sta     GPRIOR

        jmp     update_colors