chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / Sapphire / tms / s / tmsMain
1 ;
2 ; tmsMain.s
3 ;
4 ; The Straylight Tearoff Menu Segment (TMA)
5 ;
6 ; © 1994 Straylight
7 ;
8
9 ;----- Don't forget to do these things --------------------------------------
10 ;
11 ; Do a good checksum
12
13 ;----- Standard header ------------------------------------------------------
14
15                 GET     libs:header
16                 GET     libs:swis
17
18 ;----- External Dependencies ------------------------------------------------
19
20                 GET     libs:tearSupt.sh.tearsupt
21
22                 GET     sapphire:errorBox
23                 GET     sapphire:help
24                 GET     sapphire:idle
25                 GET     sapphire:keyString
26                 GET     sapphire:msgs
27                 GET     sapphire:resspr
28                 GET     sapphire:sapphire
29                 GET     sapphire:screen
30                 GET     sapphire:string
31                 GET     sapphire:tspr
32                 GET     sapphire:wimp
33                 GET     sapphire:win
34
35                 ; --- Internal header files ---
36
37                 GET     sapphire:_tms.tmsCreate
38                 GET     sapphire:_tms.tmsGlobal
39                 GET     sapphire:_tms.tmsGlue
40
41 ;----- Main code ------------------------------------------------------------
42
43                 AREA    |Sapphire$$Code|,CODE,READONLY
44
45 ; --- tms__closeMenu ---
46 ;
47 ; On entry:     R2 == pointer to menu to close
48 ;               R10 == pointer to the menu we are currently over
49 ;
50 ; On exit:      --
51 ;
52 ; Use:          Closes the menu structure pointed to, and destroys it
53
54                 EXPORT  tms__closeMenu
55 tms__closeMenu  ROUT
56
57                 CMP     R2,#0                   ;Is there menu?
58                 MOVEQS  PC,R14                  ;No -- return
59
60                 STMFD   R13!,{R0-R4,R14}        ;Stack some registers
61                 LDR     R14,tms__currDbox       ;Get the current dbox
62                 CMP     R14,R2                  ;Is this what we are closing?
63                 BEQ     %20tms__closeMenu       ;Yes -- close it then
64
65                 LDR     R0,[R2,#hPrevMenu]      ;Get the previous menu
66                 CMP     R0,#0                   ;Is there one?
67                 BEQ     %03tms__closeMenu       ;No -- skip this bit then
68                 CMP     R0,R10                  ;Are we over previous menu?
69                 BLNE    tms__deselect           ;No -- deselect the item
70                 LDREQ   R1,[R0,#hFlags]         ;Yes -- get its flags
71                 BICEQ   R1,R1,#hFlag__warned    ;...clear the warned flag
72                 STREQ   R1,[R0,#hFlags]         ;...store flags back again
73                 MOV     R0,#0                   ;A NULL pointer
74
75                 ; --- Tell the previous menu that we have closed ---
76
77                 LDR     R1,[R2,#hFromItem]      ;Get the item we are from
78                 CMP     R1,#0                   ;Is there one?
79                 STRNE   R0,[R1,#iSubMenu]       ;Yes -- no submenu now
80
81                 ; --- Update some globals ---
82
83 03              STR     R0,tms__prevLevel       ;No previous level
84                 STR     R0,tms__orgTearoff      ;No originating tearoff
85
86                 ; --- Clear the previous field of torn menus ---
87
88                 LDR     R1,tms__tornoffs        ;Get the head of the list
89                 CMP     R1,#0                   ;Are we at the end?
90                 BEQ     %05tms__closeMenu       ;Yes -- jump
91 04              LDR     R4,[R1,#hPrevMenu]      ;Get the 'previous' field
92                 CMP     R2,R4                   ;Does it point to this menu?
93                 STREQ   R0,[R1,#hPrevMenu]      ;Yes -- make it NULL
94                 LDR     R1,[R1,#hNextTorn]      ;Get the next torn menu
95                 CMP     R1,#0                   ;Are we at the end?
96                 BNE     %04tms__closeMenu       ;No -- keep looking
97
98                 ; --- If we are closing the current transient, do this ---
99
100 05              LDR     R0,tms__current         ;Point to current transient
101                 CMP     R0,R2                   ;Are we closing it?
102                 BNE     %09tms__closeMenu       ;No -- jump ahead
103                 MOV     R0,#0                   ;Yes -- A NULL pointer
104                 STR     R0,tms__current         ;...no current any more
105                 BL      tearSupport_closed      ;Stop tearoffsupt sending
106
107                 ; --- If dbox came from this menu, do this ---
108
109                 LDR     R0,tms__dboxPrev        ;Get dbox parent
110                 CMP     R0,R2                   ;Are we closing it?
111                 MOVEQ   R0,#0                   ;Yes -- get a NULL word
112                 STREQ   R0,tms__dboxPrev        ;And store that as the parent
113
114                 ; --- Now close down the menu structure ---
115
116 09              LDR     R3,tms__oldHandle       ;Get the old handle
117 10              MOV     R0,R2                   ;Destroy this menu
118                 LDR     R1,[R0,#hFlags]         ;Get the flags word
119                 TST     R1,#hFlag__torn         ;Is the menu torn off?
120                 LDMNEFD R13!,{R0-R4,PC}^        ;Yes -- return
121                 LDR     R2,[R0,#hSubMenu]       ;Get the submenu pointer
122
123                 ; --- Inform the owner about deletion ---
124
125                 STMFD   R13!,{R0-R2,R10,R12}    ;Stack some registers
126                 ADD     R0,R0,#hHandler         ;Point to the handler
127                 LDMIA   R0,{R2,R10,R12}         ;Get values out
128                 MOV     R0,#mEvent_deleted      ;The menu has been deleted
129                 MOV     R1,#0                   ;No item in question
130                 CMP     R2,#0                   ;Sanity check
131                 MOV     R14,PC                  ;Set up return address
132                 MOVNE   PC,R2                   ;Call the handler
133                 LDMFD   R13!,{R0-R2,R10,R12}    ;Get registers back
134
135                 ; --- Destroy the menu ---
136
137                 BL      tms__destroy            ;Destroy the menu
138                 CMP     R0,R3                   ;Were we over this menu?
139                 BLEQ    tms__cleanUp            ;Yes -- clean up then
140
141                 TST     R1,#hFlag__warned       ;Has there been a warning
142                 LDMEQFD R13!,{R0-R4,PC}^        ;No -- return
143                 CMP     R2,#0                   ;Is there a submenu?
144                 LDMEQFD R13!,{R0-R4,PC}^        ;No -- Return to caller
145                 TST     R1,#hFlag__dbox         ;Is this a dbox?
146                 BEQ     %10tms__closeMenu       ;No -- keep going then
147
148                 ; --- Its a window then ---
149
150 20              LDR     R0,tms__dboxPrev        ;Get the previous menu
151                 CMP     R0,#0                   ;Is there one?
152                 BEQ     %25tms__closeMenu       ;No -- skip this bit then
153                 CMP     R0,R10                  ;Are we over previous menu?
154                 BLNE    tms__deselect           ;No -- deselect the item
155                 LDREQ   R1,[R0,#hFlags]         ;Yes -- get its flags
156                 BICEQ   R1,R1,#hFlag__warned    ;...clear the warned flag
157                 STREQ   R1,[R0,#hFlags]         ;...store flags back again
158                 MOV     R0,#0                   ;A NULL pointer
159
160                 ; --- Tell the previous menu that we have closed ---
161
162                 LDR     R1,tms__dboxPrev        ;Get the item we are from
163                 CMP     R1,#0                   ;Is there one?
164                 STRNE   R0,[R1,#iSubMenu]       ;Yes -- no submenu now
165
166                 ; --- Now close the dialogue box ---
167
168 25              LDR     R2,tms__currDbox        ;Load the dbox handle
169                 STR     R2,[R13,#-4]!           ;Put handle on the stack
170                 MOV     R1,R13                  ;Point to it
171                 SWI     Wimp_CloseWindow        ;And close the window
172                 ADD     R13,R13,#4              ;Reclaim my stack
173                 MOV     R0,#0                   ;No current dbox
174                 STR     R0,tms__currDbox        ;Make that clear
175                 LDR     R1,tms__current         ;Get the current transient
176                 CMP     R1,#0                   ;Is this what we are closing?
177                 STREQ   R0,tms__current         ;Yes -- no transient now then
178                 BLEQ    tearSupport_closed      ;Stop the messages please
179                 LDR     R0,tms__flags           ;Load the main flags
180                 ORR     R0,R0,#tFlag__doFake    ;Do a fake NULL event
181                 STR     R0,tms__flags           ;Store the flags back again
182                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
183
184                 LTORG
185
186 ; --- tms__alarm1 ---
187 ;
188 ; On entry:     --
189 ;
190 ; On exit:      --
191 ;
192 ; Use:          The first alarm to be called when waiting on an item.
193
194 tms__alarm1     ROUT
195                 STMFD   R13!,{R0-R2,R7,R8,R14}  ;Stack registers nicley
196
197                 ; --- Set up the next alarm ---
198
199                 MOV     R0,#161                 ;Read the CMOS ram
200                 MOV     R1,#23                  ;Read the delay time
201                 SWI     OS_Byte                 ;Read the delay then
202                 LDR     R0,tms__flags           ;Load the tms flags
203                 ORR     R0,R0,#tFlag__nActive   ;Menus are not active
204                 STR     R0,tms__flags           ;Save the new flags
205                 ADD     R2,R2,R2,LSL #2         ;Multiply delay by 5
206                 MOV     R2,R2,LSL #1            ;And then by 2
207                 SWI     OS_ReadMonotonicTime    ;Read the current time
208                 ADD     R0,R0,R2                ;Set alarm for this time
209                 ADR     R1,tms__alarm2          ;Call this handler
210                 ADR     R2,tms__alarm1          ;Use this handle
211                 MOV     R3,R12                  ;And pass workspace in R12
212                 BL      idle_setAlarm           ;Set the alarm
213
214                 ; --- Open the sub menu ---
215
216                 LDR     R10,tms__alarmMenu      ;Get the menu alarm is for
217                 LDR     R0,[R10,#hHandle]       ;Load the window handle
218                 STR     R0,[R13,#-36]!          ;Store in a block
219                 MOV     R1,R13                  ;Point to the block
220                 SWI     Wimp_GetWindowState     ;Get the window state
221
222                 LDR     R7,tms__alarmItem       ;Get the alarm item
223                 LDR     R8,tms__itemBlock       ;Get item block address
224                 BL      tms__subMenu            ;And open the menu
225
226                 ADD     R13,R13,#36             ;Get the stack back
227                 LDMFD   R13!,{R0-R2,R7,R8,PC}^  ;Return to caller
228
229                 LTORG
230
231 ; --- tms__alarm2 ---
232 ;
233 ; On entry:     --
234 ;
235 ; On exit:      --
236 ;
237 ; Use:          Called as the second alarm, allowing selection of other
238 ;               items in the menu.
239
240 tms__alarm2     ROUT
241
242                 STMFD   R13!,{R14}              ;Stack some registers
243
244                 LDR     R14,tms__flags          ;Load the tms flags
245                 BIC     R14,R14,#tFlag__nActive ;Menus are not active
246                 STR     R14,tms__flags          ;Save the new flags
247
248                 LDMFD   R13!,{PC}^              ;Return to caller
249
250 ; --- tms__findItem ---
251 ;
252 ; On entry:     R0 == x coordinate (menu relative)
253 ;               R1 == y coordinate (menu relative)
254 ;               R10 == pointer to the menu
255 ;
256 ; On exit:      R8 == pointer to the item block
257 ;               R7 == pointer to the actual item
258
259 tms__findItem   ROUT
260
261                 STMFD   R13!,{R0-R4,R14}        ;Stack some registers
262                 MOV     R2,#0                   ;The y coordinate so far
263                 LDR     R3,[R10,#hFlags]        ;Get the menu flags
264                 TST     R3,#hFlag__tearable     ;Is there a tearoff bar?
265                 SUBNE   R2,R2,#tms__barHeight   ;Yes -- move y position down
266                 LDR     R8,[R10,#hItems]        ;Point to the items
267 00tms__findItem ADD     R7,R8,#iHdrSize         ;Point to the first item
268                 LDR     R4,[R8,#iNumber]        ;Get the item count
269 01tms__findItem CMP     R1,R2                   ;Compare y coordinates
270                 BGE     %90tms__findItem        ;If greater -- no item found
271                 SUB     R2,R2,#44               ;The bottom of the item
272                 CMP     R1,R2                   ;Compare y coordinates
273                 BGE     %10tms__findItem        ;We've found it -- jump a bit
274                 LDR     R3,[R7,#iFlags]         ;Get the item flags
275                 TST     R3,#iFlag__dotted       ;Is there a dotted line?
276                 SUBNE   R2,R2,#24               ;Subract that from y
277                 SUBS    R4,R4,#1                ;Subtract the item count
278                 ADDNE   R7,R7,#iItemSize        ;If some left, point to them
279                 BNE     %01tms__findItem        ;...and try them
280                 LDR     R8,[R8,#iItems]         ;Point to the next batch
281                 CMP     R8,#0                   ;Are there any left
282                 BNE     %00tms__findItem        ;Yes -- check them
283                 B       %90tms__findItem        ;No -- return
284
285                 ; --- We have found the item ---
286
287 10tms__findItem LDR     R1,[R8,#iDefinition]    ;Point to packed definition
288                 LDR     R0,[R8,#iNumber]        ;Get the number of items
289                 SUBS    R0,R0,R4                ;Get the index of item
290                 STR     R0,tms__itemIndex       ;Store this index value
291                 BEQ     %15tms__findItem        ;If we have found it -- jump
292 11tms__findItem LDR     R2,[R1],#4              ;Get the item flags
293                 TST     R2,#mFlag_indirect      ;Is this item indirected?
294                 ADDNE   R1,R1,#4                ;Yes -- skip the offset word
295                 BNE     %13tms__findItem        ;And skip past the loop
296
297                 ; --- Skip inline text string ---
298
299 12tms__findItem LDRB    R14,[R1],#1             ;Get a message string byte
300                 CMP     R14,#' '                ;Is it a terminator?
301                 BGE     %12tms__findItem        ;No -- get another one
302                 ADD     R1,R1,#3                ;Add 3
303                 BIC     R1,R1,#3                ;And word align the pointer
304
305                 ; --- Skip over shortcut word ---
306
307 13tms__findItem TST     R2,#mFlag_shortcut      ;It there a shortcut?
308                 TSTEQ   R2,#mFlag_iShortcut     ;Even an indirected one?
309                 ADDNE   R1,R1,#4                ;Yes -- skip over value
310
311                 ; --- Now skip other optional blocks ---
312
313                 SKPITEM R2,R1                   ;Skip this item
314                 SUBS    R0,R0,#1                ;Decrement my count
315                 BGT     %11tms__findItem        ;Keep trying if some left
316 15tms__findItem STR     R1,tms__itemOver        ;Store this pointer
317                 STR     R8,tms__itemBlock       ;And this one too
318                 LDMFD   R13!,{R0-R4,PC}^        ;And return to caller
319
320                 ; --- The pointer wasn't over an item ---
321
322 90tms__findItem MOV     R8,#0                   ;No item block found
323                 MOV     R7,#0                   ;No item found either
324                 LDMFD   R13!,{R0-R4,PC}^        ;Return now
325
326                 LTORG
327
328 ; --- tms__updateItem ---
329 ;
330 ; On entry:     R7 == pointer to the item to highlight
331 ;               R10 == pointer to the menu
332 ;
333 ; On exit:      --
334 ;
335 ; Use:          Forces an update of the textual part of an item.
336
337                 EXPORT  tms__updateItem
338 tms__updateItem ROUT
339
340                 STMFD   R13!,{R0-R4,R11,R14}    ;Stack some registers
341
342                 SUB     R13,R13,#44             ;Get a redraw block
343                 LDR     R4,[R7,#iyCoord]        ;Get the y coordinate
344                 LDR     R11,[R7,#iFlags]        ;Get the item flags
345
346                 LDR     R0,[R10,#hHandle]       ;Get the window handle
347                 MOV     R1,#24                  ;x0
348                 LDR     R3,[R10,#hTotWidth]     ;Get the total width
349                 ADD     R3,R3,#24               ;x1
350                 SUB     R2,R4,#44               ;y0
351                 STMIA   R13,{R0-R4}             ;Fill in the block
352                 MOV     R1,R13                  ;Point to it
353                 SUB     R13,R13,#32             ;Get another block
354                 SWI     Wimp_UpdateWindow       ;Start the redraw
355 00              CMP     R0,#0                   ;More to do?
356                 ADDEQ   R13,R13,#(44+32)        ;Get the stack back
357                 LDMEQFD R13!,{R0-R4,R11,PC}^    ;No -- return
358                 BL      tms__redrawText         ;Perform the redrawing
359                 BL      tms__redrawSprite       ;.,.,.,.,
360                 BL      tms__redrawKey          ;...
361                 SWI     Wimp_GetRectangle       ;Get another rectangle
362                 B       %00tms__updateItem      ;And keep redrawing
363
364                 LTORG
365
366 ; --- tms__highlight ---
367 ;
368 ; On entry:     R2 == pointer to item to highlight
369 ;               R10 == pointer to the menu for these items
370 ;
371 ; On exit:      --
372 ;
373 ; Use:          Highlights the item pointed to on entry
374
375 tms__highlight  ROUT
376
377                 STMFD   R13!,{R0,R7,R14}        ;Stack some registers
378                 LDR     R0,[R10,#hSelected]     ;Get the selected item
379                 CMP     R2,R0                   ;Are they the same
380                 STMEQFD R13!,{R0-R4,R7,PC}^     ;Yes -- return
381                 MOV     R7,R2                   ;Point to the item
382                 STR     R7,[R10,#hSelected]     ;This is now selected item
383                 LDR     R0,[R7,#iFlags]         ;Get the item flags
384                 TST     R0,#iFlag__shaded       ;Is the item shaded?
385                 BLEQ    tms__updateItem         ;No -- update it
386                 LDMFD   R13!,{R0,R7,PC}^        ;And return
387
388                 LTORG
389
390 ; --- tms__unHighlight ---
391 ;
392 ; On entry:     R2 == pointer to item to un-highlight
393 ;               R10 == pointer to the menu for these items
394 ;
395 ; On exit:      --
396 ;
397 ; Use:          un-highlights the item pointed to on entry
398
399 tms__unHighlight ROUT
400
401                 STMFD   R13!,{R0,R7,R14}        ;Stack some registers
402                 LDR     R0,[R10,#hSelected]     ;Get the selected item
403                 CMP     R2,R0                   ;Are they the same?
404                 LDMNEFD R13!,{R0,R7,PC}^        ;No -- return
405                 MOV     R7,R2                   ;Point to the item
406                 MOV     R0,#0                   ;No selected item
407                 STR     R0,[R10,#hSelected]     ;Store the NULL pointer
408                 LDR     R0,[R7,#iFlags]         ;Get the item flags
409                 TST     R0,#iFlag__shaded       ;Is the item shaded?
410                 BLEQ    tms__updateItem         ;No -- update it
411                 LDMFD   R13!,{R0,R7,PC}^        ;And return
412
413                 LTORG
414
415 ; --- tms__deselect ---
416 ;
417 ; On entry:     R0 == pointer to the menu
418 ;
419 ; On exit:      --
420 ;
421 ; Use:          Deselects the highlighted item in the given menu
422
423 tms__deselect   ROUT
424
425                 STMFD   R13!,{R2,R10,R14}       ;Stack some registers
426                 LDR     R2,[R0,#hSelected]      ;Point to the selected item
427                 CMP     R2,#0                   ;Is there one?
428                 LDMEQFD R13!,{R2,R10,PC}^       ;No -- return then
429
430                 MOV     R10,R0                  ;We need menu in R10
431                 BL      tms__unHighlight        ;Unhighlight it then
432                 LDR     R14,[R0,#hFlags]        ;Get the flags word
433                 BIC     R14,R14,#hFlag__warned  ;We are no longer warned
434                 STR     R14,[R0,#hFlags]        ;Store back modified flags
435                 LDMFD   R13!,{R2,R10,PC}^       ;Return to caller
436
437                 LTORG
438
439 ; --- tmsh__subWaiting ---
440 ;
441 ; On entry:     --
442 ;
443 ; On exit:      CS if we're waiting for a submenu, CC otherwise
444 ;
445 ; Use:          Informs transWin if a submenu is expected.
446
447                 EXPORT  tmsh__subWaiting
448 tmsh__subWaiting ROUT
449
450                 STMFD   R13!,{R12,R14}          ;Save some registers
451                 WSPACE  tms__wSpace             ;Load my workspace address
452                 LDR     R14,tms__flags          ;Load the flags word
453                 TST     R14,#tFlag__subWait     ;Are we waiting for a submenu
454                 LDMFD   R13!,{R12,R14}          ;Unstack the registers
455                 ORRNES  PC,R14,#C_flag          ;Yes -- return CS then
456                 BICEQS  PC,R14,#C_flag          ;No -- return CC then
457
458                 LTORG
459
460 ; --- tmsh__openSub ---
461 ;
462 ; On entry:     R0 == window handle to open
463 ;
464 ; On exit:      --
465 ;
466 ; Use:          Opens the given window as a submenu from a tms menu.
467
468                 EXPORT  tmsh__openSub
469 tmsh__openSub   ROUT
470
471                 STMFD   R13!,{R0-R3,R12,R14}    ;Save registers
472                 WSPACE  tms__wSpace             ;Load my workspace address
473                 STR     R0,[R13,#-36]!          ;Get a block
474                 LDR     R1,tms__currItem        ;Point to the current item
475                 STR     R0,[R1,#iDbox]          ;Store the window handle
476                 LDR     R14,[R1,#iFlags]        ;Load the flags word
477                 ORR     R14,R14,#iFlag__dbox    ;Say this is a dbox
478                 STR     R14,[R1,#iFlags]        ;Save the flags back
479                 STR     R0,tms__currDbox        ;Store it here too
480                 LDR     R1,tms__orgTearoff      ;Load the originating tearoff
481                 STR     R0,[R1,#hDbox]          ;Store the window handle
482                 LDR     R14,[R1,#hFlags]        ;Load the flags word
483                 ORR     R14,R14,#hFlag__dbox    ;Say this is a dbox
484                 STR     R14,[R1,#hFlags]        ;Save the flags back
485                 STR     R0,[R1,#hSubMenu]       ;Store as submenu
486                 STR     R1,tms__dboxPrev        ;This is menu dbox came from
487
488                 LDR     R14,tms__current        ;Load the current transient
489                 CMP     R14,#0                  ;Is there one?
490                 BLEQ    wimp_taskHandle         ;No -- get task handle  
491                 BLEQ    tearSupport_opened      ;...start tearSupt then
492                 
493                 MOV     R1,R13                  ;Point to it
494                 SWI     Wimp_GetWindowState     ;Get the window state
495                 LDMIB   R1,{R0-R3}              ;Get the current coords
496                 SUB     R2,R2,R0                ;Get the current width
497                 SUB     R1,R3,R1                ;And its height
498                 ADR     R0,tms__coords          ;Get coords to open at
499                 LDMIA   R0,{R0,R3}              ;Load some coords then
500                 SUB     R1,R3,R1                ;Calculate y0 coord
501                 ADD     R2,R0,R2                ;And then x1
502                 STMIB   R13,{R0-R3}             ;Store them back nicely
503                 MOV     R0,#-1                  ;Open at the front please
504                 STR     R0,[R13,#28]            ;Store this in the block
505                 MOV     R1,R13                  ;Point back to the block
506                 BL      tspr_adjustBox          ;Fit on screen properly
507                 SWI     Wimp_OpenWindow         ;Open the window
508                 ADD     R13,R13,#36             ;Restore stack
509                 LDMFD   R13!,{R0-R3,R12,PC}^    ;Return to caller
510
511                 LTORG
512
513 ; --- tms__subMenu ---
514 ;
515 ; On entry:     R1 == pointer to a window state for the menu
516 ;               R7 == pointer to the item
517 ;               R8 == pointer to item header block
518 ;               R10 == pointer to the menu
519 ;               R12 == workspace pointer
520 ;
521 ; On exit:      --
522 ;
523 ; Use:          Opens the sub menu correctly for the given item.
524
525 tms__subMenu    ROUT
526                 STMFD   R13!,{R0-R6,R14}        ;Stack some registers
527
528                 ; --- Store the coords to open next menu ---
529
530                 LDR     R4,[R1,#12]             ;Get the x1 coordinate
531                 LDR     R5,[R1,#16]             ;...and y1
532                 ADD     R4,R4,#2                ;Correct x1 a bit
533                 LDR     R6,[R7,#iyCoord]        ;Get the y coord of item
534                 ADD     R5,R5,R6                ;Calculate next y to open at
535                 LDR     R6,[R1,#24]             ;Don't forget scroll offset
536                 SUB     R5,R5,R6                ;No siree
537                 ADR     R6,tms__coords          ;Point to the coords
538                 STMIA   R6,{R4,R5}              ;Store the coordinates
539
540                 ; --- Warn the user/open the menu if we need to ---
541
542                 LDR     R6,[R10,#hFlags]        ;Get the menu flags
543                 TST     R6,#hFlag__warned       ;Have we already been warned?
544                 BNE     %35tms__subMenu         ;Yes -- skip this bit
545                 ORR     R6,R6,#hFlag__warned    ;We have been now
546                 STR     R6,[R10,#hFlags]        ;Store back the flags
547                 LDR     R4,[R7,#iSubMenu]       ;Get the submenu ptr
548                 CMP     R4,#0                   ;Is there one?
549                 BLNE    tms__locateMenu         ;Yes -- try to find it
550                 CMP     R4,#0                   ;Has it been returned?
551                 BNE     %37tms__subMenu         ;Yes -- bring it back to us
552                 STR     R6,[R10,#hFlags]        ;Store the flags back
553                 TST     R6,#hFlag__torn         ;Is menu torn off?
554                 STRNE   R10,tms__orgTearoff     ;Yes -- remember this fact
555                 MOV     R5,#0                   ;A NULL pointer
556                 STR     R5,[R10,#hSubMenu]      ;No current sub menu
557                 STR     R10,tms__prevLevel      ;This is the previous menu
558                 LDR     R4,tms__itemOver        ;Get packed defn for item
559                 LDR     R3,[R4],#4              ;Get the flags word
560                 TST     R3,#mFlag_subWarn       ;Do we require a warning?
561                 BNE     %33tms__subMenu         ;Yes -- deal with it
562                 TST     R3,#mFlag_indirect      ;Is this item indirected?
563                 ADDNE   R4,R4,#4                ;Yes -- skip the offset word
564                 BNE     %32tms__subMenu         ;And skip past the loop
565
566                 ; --- Skip inline text string ---
567
568 31tms__subMenu  LDRB    R14,[R4],#1             ;Get a message string byte
569                 CMP     R14,#' '                ;Is it a terminator?
570                 BGE     %31tms__subMenu         ;No -- get another one
571                 ADD     R4,R4,#3                ;Add 3
572                 BIC     R4,R4,#3                ;And word align the pointer
573
574                 ; --- Now skip other optional blocks ---
575
576 32tms__subMenu  TST     R3,#mFlag_shortcut      ;Is there a normal...
577                 TSTEQ   R3,#mFlag_iShortcut     ;...or indirected shortcut?
578                 ADDNE   R4,R4,#4                ;Yes -- skip over it
579                 SKIP    mFlag_shade,4,R3,R4
580                 SKIP    mFlag_iShade,4,R3,R4
581                 SKIP    mFlag_switch,4,R3,R4
582                 SKIP    mFlag_radio,8,R3,R4
583                 SKIP    mFlag_sprite,8,R3,R4
584
585                 ; --- We are now pointing at submenu information ---
586
587                 LDR     R0,[R4,#0]              ;Point to packed definition
588                 LDR     R1,[R4,#4]              ;Point to the event handler
589                 LDR     R2,[R8,#iR10]           ;Use R10 from previous item
590                 LDR     R3,[R8,#iR12]           ;Use R12 from previous item
591                 BL      tms__searchForMenu      ;Does this menu exist?
592                 BCS     %37tms__subMenu         ;Yes -- get it back then
593                 BL      tms_create              ;Create the menu
594                 STR     R0,[R7,#iSubMenu]       ;Store this in item defn
595                 STR     R7,[R0,#hFromItem]      ;We came from this item
596                 B       %40tms__subMenu         ;Now deal with real clicks
597
598                 ; --- The user requires a submenu warning ---
599
600 33tms__subMenu  LDR     R0,[R7,#iFlags]         ;Get the item flags
601                 TST     R0,#iFlag__shaded       ;Is the item shaded?
602                 TSTNE   R0,#iFlag__noWarn       ;And we don't want warning?
603                 BNE     %40tms__subMenu         ;Both -- return
604                 MOV     R0,#mEvent_arrow        ;Send this event type
605                 LDR     R1,tms__itemIndex       ;With this index
606                 STR     R7,tms__currItem        ;Save the current item
607                 STR     R10,tms__orgTearoff     ;The originating menu
608                 LDR     R14,tms__flags          ;Load my current flags
609                 ORR     R14,R14,#tFlag__subWait ;We're waiting for a submenu
610                 STR     R14,tms__flags          ;Save the flags back
611                 STMFD   R13!,{R10,R12}          ;Save these registers
612                 ADD     R3,R8,#iHandler         ;Point to the handler
613                 LDMIA   R3,{R3,R10,R12}         ;Load the values
614                 ADDS    R0,R0,#0                ;Clear the carry flag
615                 TEQ     R3,#0                   ;Sanity check
616                 MOV     R14,PC                  ;Set up the return address
617                 MOVNE   PC,R3                   ;Call the handler
618                 LDMFD   R13!,{R10,R12}          ;Get my registers back
619                 LDR     R14,tms__flags          ;Load my current flags
620                 BIC     R14,R14,#tFlag__subWait ;Stopped waiting for submenu
621                 STR     R14,tms__flags          ;Save the flags back
622
623                 ; --- Use must return with menu in R0, and carry set if
624                 ;     menu is already open.
625
626                 STR     R0,[R7,#iSubMenu]       ;Store this in item defn
627                 TEQ     R0,#0                   ;Has user returned NULL?
628                 STRNE   R7,[R0,#hFromItem]      ;No -- we came from this item
629
630                 MOVCS   R4,R0                   ;If carry set...
631                 BCS     %37tms__subMenu         ;...reposition given menu
632                 B       %40tms__subMenu         ;Return to caller
633
634                 ; --- There has already been a warning ---
635
636 35tms__subMenu  LDR     R4,[R10,#hSubMenu]      ;Get the submenu pointer
637                 CMP     R4,#0                   ;Is there one?
638                 BEQ     %40tms__subMenu         ;No -- return to caller
639                 LDR     R14,[R7,#iFlags]        ;Get the item flags
640                 TST     R14,#iFlag__dbox        ;Is this a dbox?
641                 BNE     %40tms__subMenu         ;Yes -- return to caller
642                 LDR     R5,[R4,#hFlags]         ;Get flags for sub menu
643                 TST     R5,#hFlag__warned       ;Does submenu have submenu?
644                 BEQ     %36tms__subMenu         ;No -- jump this bit
645                 LDR     R2,[R4,#hSubMenu]       ;Point to the submenu's sub
646                 BL      tms__closeMenu          ;Close it down
647                 MOV     R0,R4                   ;Point to the submenu
648                 BL      tms__deselect           ;Deselect highlighted item
649
650                 ; --- Reposition the sub menu ---
651
652 36tms__subMenu  SUB     R13,R13,#36             ;Get me a block
653                 LDR     R5,[R4,#hHandle]        ;Get the window handle
654                 STR     R5,[R13,#0]             ;Store it in the block
655                 MOV     R1,R13                  ;Point to the block
656                 SWI     Wimp_GetWindowState     ;Get the window state then
657                 LDR     R5,[R13,#12]            ;Get x1
658                 LDR     R1,[R13,#4]             ;Get x0
659                 SUB     R5,R5,R1                ;Get the window width
660                 LDR     R1,tms__coords          ;Get the x position to open
661                 STR     R1,[R13,#4]             ;Store this in the block
662                 ADD     R5,R5,R1                ;Get new x1 position
663                 STR     R5,[R13,#12]            ;Store this too
664
665                 LDR     R5,[R13,#16]            ;Get y1
666                 LDR     R1,[R13,#8]             ;Get y0
667                 SUB     R5,R5,R1                ;Get the window height
668                 LDR     R1,tms__coords+4        ;Get the y position to open
669                 LDR     R3,[R4,#hFlags]         ;Get the menu flags
670                 TST     R3,#hFlag__tearable     ;Is there a bar?
671                 ADDNE   R1,R1,#tms__barHeight   ;Yes -- add this on
672                 STR     R1,[R13,#16]            ;Store this in the block
673                 SUB     R5,R1,R5                ;Get new y0 position
674                 STR     R5,[R13,#8]             ;Store this too
675                 MOV     R1,#-1                  ;Open in front
676                 STR     R1,[R13,#28]            ;Store this value too
677                 MOV     R1,R13                  ;Point to the block
678                 BL      tspr_adjustBox          ;Mangle to fit on screen
679                 SWI     Wimp_OpenWindow         ;Open the window
680                 ADD     R13,R13,#36             ;Get my stack back
681                 B       %40tms__subMenu         ;Deal with real clicks
682
683                 ; --- We need to 'bring back' a torn off menu ---
684
685 37tms__subMenu  MOV     R5,R10                  ;Remember R10 value
686                 MOV     R10,R4                  ;Point at found menu
687                 BL      tms__unTearMenu         ;Un-tear it
688                 BL      tms__updateBar          ;Update the tearoff bar
689                 MOV     R10,R5                  ;Get R10 value back
690                 STR     R4,[R7,#iSubMenu]       ;Store submenu pointer back
691                 STR     R4,[R10,#hSubMenu]      ;...in places good
692                 STR     R10,[R4,#hPrevMenu]     ;Store previous menu
693                 STR     R7,[R4,#hFromItem]      ;Item menu was from
694                 LDR     R5,tms__current         ;Get the current menu
695                 CMP     R5,#0                   ;Is there one?
696                 STREQ   R4,tms__current         ;No -- store this one then
697                 BLEQ    wimp_taskHandle         ;...get the task handle
698                 BLEQ    tearSupport_opened      ;...start tearoffsupt sending
699
700                 B       %36tms__subMenu         ;And reposition it
701
702 40tms__subMenu  LDMFD   R13!,{R0-R6,PC}^        ;Return to caller
703
704                 LTORG
705
706 ; --- tms__buttons ---
707 ;
708 ; On entry:     R1 == pointer to mousepointer info block
709 ;               R10 == pointer to the menu
710 ;
711 ; On exit:      --
712 ;
713 ; Use:          Called when a button event is detected on a menu, or
714 ;               for NULL events (with button type 0)
715
716 tms__buttons    ROUT
717
718                 STMFD   R13!,{R0-R9,R14}        ;Stack some registers
719
720                 LDR     R14,tms__flags          ;Get the current flags
721                 TST     R14,#tFlag__nActive     ;Are we active?
722                 BNE     %99tms__buttons         ;No -- return
723
724                 ; --- First we deal with *any* button type ---
725
726                 MOV     R9,R1                   ;Keep a pointer to the block
727                 SUB     R13,R13,#36             ;Get a small block
728                 MOV     R1,R13                  ;Point to the block
729                 LDR     R2,[R10,#hHandle]       ;Get the window handle
730                 STR     R2,[R1,#0]              ;Store the window handle
731                 SWI     Wimp_GetWindowState     ;Get the window state
732                 MOV     R8,R1                   ;Remember this pointer
733                 LDR     R0,[R9,#0]              ;Get the mouse x coord
734                 LDR     R2,[R8,#20]             ;Get the scroll x position
735                 LDR     R3,[R8,#4]              ;Get the x0 position
736                 ADD     R0,R0,R2                ;Calculate workarea relative
737                 SUB     R0,R0,R3                ;...x position
738                 LDR     R1,[R9,#4]              ;Get the mouse y coord
739                 LDR     R2,[R8,#24]             ;Get the scroll y position
740                 LDR     R3,[R8,#16]             ;Get the y1 position
741                 ADD     R1,R1,R2                ;Calculate workarea relative
742                 SUB     R1,R1,R3                ;...y position
743                 STMIA   R9,{R0,R1}              ;Store back updated positions
744                 LDR     R6,tms__flags           ;Get the flags
745                 BL      tms__findItem           ;Find the item we are over
746                 CMP     R8,#0                   ;Did we find an item
747                 BEQ     %12tms__buttons         ;No -- jump ahead a bit
748                 LDR     R5,[R10,#hTotWidth]     ;Get the width
749                 SUB     R5,R5,#24               ;The right hand edge
750                 CMP     R0,R5                   ;Are we over it?
751
752                 ; --- Complex condition time ---
753                 ;
754                 ; The following code should only be executed if:
755                 ;    we're over a sub menu arrow AND we were
756                 ;    not over it before
757                 ;  OR
758                 ;    we are not over a submenu arrow at all AND the
759                 ;    item isn't the alarm item
760
761                 BIC     R6,R6,#tFlag__overArrow ;We are not over an arrow
762                 BLT     %10tms__buttons         ;We cannot be over an arrow
763                 LDR     R5,tms__itemOver        ;Get a pointer to the item
764                 LDR     R5,[R5,#0]              ;Get the item flags
765                 MVN     R5,R5                   ;Invert them!
766                 AND     R5,R5,#mFlag_subMenu+mFlag_subWarn ; Keep these bits
767                 CMP     R5,#mFlag_subMenu+mFlag_subWarn ;Is there no arrow?
768
769                 ; Here, EQ if we are not over an arrow, NE otherwise ---
770
771                 BEQ     %10tms__buttons         ;Jump if we're not over arrow
772                 ORR     R6,R6,#tFlag__overArrow ;We are over an arrow
773                 STR     R6,tms__flags           ;Store the flags
774                 LDR     R5,[R10,#hSelected]     ;Get the selected item
775                 CMP     R7,R5                   ;Are they the same?
776                 BEQ     %30tms__buttons         ;Yes -- jump this section
777
778                 ; --- Well, the condition has been met at this point ---
779
780 10tms__buttons  STR     R6,tms__flags           ;Store the flags
781                 LDR     R0,tms__alarmItem       ;Get item alarm is for
782                 CMP     R0,R7                   ;Are they the same?
783                 BEQ     %30tms__buttons         ;Yes -- jump this section
784                 LDR     R0,tms__alarmItem       ;Get item alarm is for
785                 CMP     R0,R7                   ;Are they the same?
786                 BEQ     %30tms__buttons         ;Yes -- jump this section
787
788         ;       LDR     R6,[R10,#hFlags]        ;Get the menu flags
789         ;       TST     R6,#hFlag__tearable     ;Is there a bar?
790         ;       BEQ     %11tms__buttons         ;No -- jump ahead
791         ;       CMP     R1,#-tms__barHeight     ;Is it in the bar
792         ;       BGE     %12tms__buttons         ;Yes -- jump past this bit
793
794                 ; --- Close the current RISCOS menu using tearoff support ---
795
796 11tms__buttons  STMFD   R13!,{R0-R1}            ;Stack these now
797                 MOV     R0,#1                   ;Switch off SWI vectoring
798                 BL      tearSupport_switch      ;Yes siree bob matey
799                 MOV     R1,#-1                  ;No menu please Mr. Wimp
800                 SWI     XWimp_CreateMenu        ;La de dar do
801                 MOVVC   R0,#0                   ;Switch vectoring back on
802                 BLVC    tearSupport_switch      ;Please
803                 LDMFD   R13!,{R0-R1}            ;Get coords back back
804
805                 ; --- If the menu is torn off, then close transient ---
806
807                 LDR     R5,[R10,#hFlags]        ;Get the menu flags
808                 TST     R5,#hFlag__torn         ;Has menu been torn off?
809                 BEQ     %12tms__buttons         ;No -- skip ahead
810                 LDR     R2,tms__current         ;Point to current transient
811                 CMP     R2,#0                   ;Is there one?
812                 LDREQ   R2,tms__currDbox        ;No -- load dbox handle
813                 BL      tms__closeMenu          ;Close the menu
814                 B       %13tms__buttons         ;Skip the next bit
815
816                 ; --- If there is already a menu open from here, close it ---
817
818 12tms__buttons  LDR     R5,[R10,#hFlags]        ;Get the menu flags
819                 TST     R5,#hFlag__warned       ;Has there been a warning?
820                 BEQ     %13tms__buttons         ;No -- skip ahead
821                 LDR     R2,[R10,#hSubMenu]      ;Get its submenu
822                 BL      tms__closeMenu          ;Close the submenu
823                 BIC     R5,R5,#hFlag__dbox      ;There is no dbox now
824                 STR     R5,[R10,#hFlags]        ;Store the flags back
825                 CMP     R7,#0                   ;Is there an item?
826                 LDRNE   R6,[R7,#iFlags]         ;Yes -- get the menu flags
827                 BICNE   R6,R6,#iFlag__dbox      ;...not a dbox
828                 STRNE   R6,[R7,#iFlags]         ;...store flags back again
829                 MOV     R2,#0                   ;A NULL pointer
830                 STR     R2,[R10,#hSubMenu]      ;No sub menu any more
831
832                 ; --- Cause a fake event if we just closed a dbox ---
833
834 13tms__buttons  LDR     R0,tms__flags           ;Load the flags word
835                 TST     R0,#tFlag__doFake       ;Should we do a fake?
836                 BNE     %90tms__buttons         ;Yes -- return to caller
837
838                 ; --- Do the selecting/deselecting ---
839
840                 LDR     R5,[R10,#hSelected]     ;Get the selected item
841                 CMP     R7,R5                   ;Are they the same?
842                 BEQ     %15tms__buttons         ;Yes -- do nothing here
843                 CMP     R5,#0                   ;Is there a selected item
844                 BEQ     %14tms__buttons         ;No -- skipitty jump
845                 LDR     R6,[R5,#iFlags]         ;Get the flags for this item
846                 TST     R6,#iFlag__shaded       ;Is it shaded?
847                 BNE     %14tms__buttons         ;Yes -- skipitty jump
848                 MOV     R2,R5                   ;Unhighlight this item
849                 BL      tms__unHighlight        ;Unhighlight it then
850 14tms__buttons  MOVS    R2,R7                   ;Point to the item
851                 BLNE    tms__highlight          ;Yes -- highlight the item
852                 STR     R2,[R10,#hSelected]     ;Store pointer to item
853                 ADRL    R0,tms__alarm1          ;Remove alarms with this hnd
854                 BL      idle_removeAllAlarms    ;Do it then
855                 MOV     R0,#-1                  ;No alarm set
856                 STR     R0,tms__alarmItem       ;So say that
857
858                 ; --- Do we need to set an alarm? ---
859
860 15tms__buttons  CMP     R7,#0                   ;Is there an item?
861                 BEQ     %20tms__buttons         ;No -- don't set an alarm
862                 LDR     R6,[R7,#iFlags]         ;Get the flags word
863                 TST     R6,#iFlag__arrow        ;Are we over an arrow?
864                 BEQ     %20tms__buttons         ;No -- don't set an alarm
865
866                 LDR     R0,tms__alarmItem       ;Get the current alarm item
867                 CMP     R0,#-1                  ;Is there one?
868                 BNE     %20tms__buttons         ;Yes -- skip ahead
869                 BL      wimp_version            ;Get the wimp version
870                 CMP     R0,#300                 ;Higher than RISC OS 2?
871                 BLT     %20tms__buttons         ;No -- don't do this then
872
873                 ; --- Check with the CMOS setting ---
874
875                 MOV     R0,#161                 ;Read CMOS
876                 MOV     R1,#197                 ;The wimp flags
877                 SWI     XOS_Byte                ;Read them then
878                 TST     R2,#&80                 ;Is the bit set?
879                 BEQ     %20tms__buttons         ;No -- don't do this then
880                 MOV     R0,#161                 ;Read CMOS
881                 MOV     R1,#23                  ;Read the delay time
882                 SWI     XOS_Byte                ;Read it then
883                 CMP     R2,#0                   ;Is there a sensible time?
884                 BEQ     %20tms__buttons         ;No -- don't do this then
885
886                 ; --- Right, set the alarm ---
887
888                 STR     R10,tms__alarmMenu      ;Alarm is for this menu
889                 STR     R7,tms__alarmItem       ;And for this item
890                 ADD     R1,R2,R2,LSL #2         ;Multiply time by 5
891                 MOV     R1,R1,LSL #1            ;And then by 2 (10 in all)
892                 SWI     OS_ReadMonotonicTime    ;Read the current time
893                 ADD     R0,R0,R1                ;Set alarm for this time
894                 ADRL    R1,tms__alarm1          ;Point to handler function
895                 MOV     R2,R0                   ;Use that as the handle
896                 MOV     R3,R12                  ;Pass workspace in R12
897                 BL      idle_setAlarm           ;And set the alarm
898
899                 ; --- Correct some 'variables' ---
900
901 20tms__buttons  LDR     R6,[R10,#hFlags]        ;Get the menu flags
902                 BIC     R6,R6,#hFlag__warned    ;We haven't been warned
903                 BIC     R6,R6,#hFlag__dbox      ;And there is not a dbox
904                 STR     R6,[R10,#hFlags]        ;Store the flags back again
905                 CMP     R7,#0                   ;Is there an item?
906                 MOV     R6,#0                   ;A NULL pointer
907                 STR     R6,tms__prevLevel       ;No previous level
908                 STR     R6,tms__orgTearoff      ;No originating tearoff
909
910                 ; --- Well, that lots over, no where near finished though ---
911
912                 ; --- Are we over a sub menu arrow? ---
913
914 30tms__buttons  CMP     R7,#0                   ;Is there an item?
915                 BEQ     %40tms__buttons         ;No -- deal with real clicks
916                 LDR     R6,tms__flags           ;Get the flags word
917                 TST     R6,#tFlag__overArrow    ;Are we over an arrow?
918                 BEQ     %40tms__buttons         ;No -- skip this bit
919
920                 ; --- The pointer is over an arrow ---
921
922                 MOV     R1,R13                  ;Point to the window state
923                 BL      tms__subMenu            ;Open the sub menu
924
925                 ; --- Deal with real buttons clicks ---
926
927 40tms__buttons  LDR     R2,[R9,#8]              ;Get the button status
928                 CMP     R2,#0                   ;Was a button pressed?
929                 BEQ     %90tms__buttons         ;No -- return
930
931                 ; --- Was the click on the tearoff bar? ---
932
933                 LDR     R0,tms__flags           ;Get the flags word
934                 TST     R2,#6                   ;Select or menu pressed?
935                 ORRNE   R0,R0,#tFlag__close     ;Yes -- close the transient
936                 BICEQ   R0,R0,#tFlag__close     ;No -- keep it open
937                 STR     R0,tms__flags           ;Store the flags back
938                 LDMIA   R9,{R0,R1}              ;Get the coordiantes
939                 LDR     R2,[R10,#hFlags]        ;Get the menu flags
940                 TST     R2,#hFlag__tearable     ;Is there a bar?
941                 BEQ     %50tms__buttons         ;No -- branch ahead
942                 CMP     R1,#-tms__barHeight     ;Did we click in the bar?
943                 BLT     %50tms__buttons         ;No -- branch ahead
944                 CMP     R1,#-4                  ;The top of the icon
945                 BGT     %90tms__buttons         ;Not in icon -- return
946                 CMP     R1,#-(tms__barHeight-4) ;The bottom level
947                 BLT     %90tms__buttons         ;Not in icon -- return
948                 TST     R2,#hFlag__torn         ;Has the menu been torn off
949                 BNE     %45tms__buttons         ;Yes -- deal with that
950
951                 ; --- Was the click in the tear icon? ---
952
953                 CMP     R0,#4                   ;The left hand side
954                 BLT     %90tms__buttons         ;Not in icon -- return
955                 CMP     R0,#68                  ;The right hand side
956                 BGT     %90tms__buttons         ;Not in icon -- return
957                 BL      tms__tearMenu           ;Tear the menu off
958                 B       %90tms__buttons         ;Return to caller
959
960                 ; --- The menu is torn off -- what did we click in? ---
961
962 45tms__buttons  CMP     R0,#4                   ;The left hand side
963                 BLT     %90tms__buttons         ;Not in icon -- return
964                 CMP     R0,#70                  ;The right hand side
965                 BLLE    tms__closeTornMenu      ;Tear the menu off
966                 BLE     %90tms__buttons         ;Return to caller
967
968                 ; --- Was it in the fold icon ---
969
970 46tms__buttons  LDR     R2,[R10,#hTotWidth]     ;The total menu width
971                 SUB     R2,R2,#60               ;LHS of tear icon
972                 CMP     R0,R2                   ;Where did we click?
973                 BLT     %90tms__buttons         ;Not in it, that's for sure
974                 ADD     R2,R2,#56               ;RHS of tear icon
975                 CMP     R0,R2                   ;Where did we click?
976                 BGT     %90tms__buttons         ;Not in it, that's for sure
977                 BL      tms__foldMenu           ;Fold the menu then
978                 B       %90tms__buttons         ;Return to caller
979
980                 ; --- The click was on an item ---
981
982 50tms__buttons  CMP     R7,#0                   ;Is there an item here?
983                 BEQ     %90tms__buttons         ;No -- return
984                 LDR     R0,[R7,#iFlags]         ;Get the item flags
985                 TST     R0,#iFlag__shaded       ;Is the item shaded
986                 BNE     %90tms__buttons         ;Yes -- return then
987
988                 MOV     R3,#3                   ;Flash this many times
989                 MOV     R0,#19                  ;VSync
990 51tms__buttons  SWI     OS_Byte                 ;Wait for it
991                 SWI     OS_Byte                 ;Wait for it again
992                 MOV     R2,R7                   ;Point to the item
993                 BL      tms__unHighlight        ;Unhighlight item
994                 SWI     OS_Byte                 ;Wait for VSync
995                 SWI     OS_Byte                 ;Wait for it again
996                 MOV     R2,R7                   ;Point to the item
997                 BL      tms__highlight          ;Highlight item
998                 SUBS    R3,R3,#1                ;Decrement counter
999                 BNE     %51tms__buttons         ;Flash more times if needed
1000
1001                 ; --- Close the menu structure if we need to ---
1002
1003                 LDR     R0,tms__flags           ;Get the flags word
1004                 TST     R0,#tFlag__close        ;Should I close the menu?
1005                 LDRNE   R2,tms__current         ;Yes -- point to current menu
1006                 BLNE    tms__closeMenu          ;...and close the transient
1007
1008                 ; --- Finally, report event to the user ---
1009
1010                 STMFD   R13!,{R10,R12}          ;Save these registers
1011                 MOV     R0,#mEvent_select       ;Item has been selected
1012                 LDR     R1,tms__itemIndex       ;The items index
1013                 ADD     R3,R8,#iHandler         ;Point to the handler
1014                 LDMIA   R3,{R3,R10,R12}         ;Load the values
1015                 ADDS    R0,R0,#0                ;Clear the carry flag
1016                 TEQ     R3,#0                   ;Sanity check
1017                 MOV     R14,PC                  ;Set up the return address
1018                 MOVNE   PC,R3                   ;Call the handler
1019                 LDMFD   R13!,{R10,R12}          ;Get my registers back
1020
1021                 BL      tms_recreate            ;Recreate the existing menus
1022
1023                 ; --- Return to the user ---
1024
1025 90tms__buttons  ADD     R13,R13,#36             ;Reclaim my stack
1026 99tms__buttons  LDMFD   R13!,{R0-R9,PC}^        ;And return to caller
1027
1028                 LTORG
1029
1030 ; --- tms__cleanUp ---
1031 ;
1032 ; On entry:     R0 == handle idle handler is called with (the menu)
1033 ;
1034 ; On exit:      --
1035 ;
1036 ; Use:          Called to clean up the system when the pointer has left
1037 ;               a menu.
1038
1039                 EXPORT  tms__cleanUp
1040 tms__cleanUp    ROUT
1041
1042                 STMFD   R13!,{R0-R3,R14}        ;Stack some registers
1043                 MOV     R2,R0                   ;The R10 value
1044                 ADRL    R1,tms__idleHandler     ;The routine that is called
1045                 MOV     R0,#0                   ;How frequently it was called
1046                 MOV     R3,R12                  ;The R12 value passed
1047                 BL      idle_removeHandler      ;Remove the handler
1048                 MOV     R0,#0                   ;No handler set up
1049                 STR     R0,tms__oldHandle       ;Store that fact
1050                 ADRL    R0,tms__alarm1          ;Remove alarms with this hnd
1051                 BL      idle_removeAllAlarms    ;Do it then
1052                 MOV     R0,#-1                  ;No alarm set
1053                 STR     R0,tms__alarmItem       ;So say that
1054                 BL      tms__alarm2             ;Allow item selection
1055
1056                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
1057
1058                 LTORG
1059
1060
1061 ; --- tms__updateBar ---
1062 ;
1063 ; On entry:     R10 == pointer to the menu
1064 ;
1065 ; On exit:      --
1066 ;
1067 ; Use:          Update the tearoff bar of the given menu
1068
1069 tms__updateBar  ROUT
1070
1071                 STMFD   R13!,{R0-R4,R14}        ;Stack some registers
1072
1073                 SUB     R13,R13,#44             ;Get me a block
1074                 LDR     R0,[R10,#hHandle]       ;Get the window handle
1075                 MOV     R1,#0                   ;x0
1076                 LDR     R3,[R10,#hTotWidth]     ;Get the total width
1077                 ADD     R3,R3,#48               ;x1
1078                 MOV     R2,#-tms__barHeight     ;y0
1079                 MOV     R4,#0                   ;y1
1080                 STMIA   R13,{R0-R4}             ;Fill in the block
1081                 MOV     R1,R13                  ;Point to it
1082                 MOV     R4,R2                   ;The y coordinate
1083                 SUB     R13,R13,#32             ;Get another block
1084                 SWI     Wimp_UpdateWindow       ;Start the redraw
1085 00              CMP     R0,#0                   ;More to do?
1086                 BEQ     %10tms__updateBar       ;No -- return
1087                 BL      tms__redrawBar          ;Perform the redrawing
1088                 SWI     Wimp_GetRectangle       ;Get another rectangle
1089                 B       %00tms__updateBar       ;And keep redrawing
1090
1091 10              ADD     R13,R13,#(44+32)        ;Get the stack back
1092                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
1093
1094                 LTORG
1095
1096 ; --- tms__tearMenu ---
1097 ;
1098 ; On entry:     R10 == pointer to menu to tear off
1099 ;
1100 ; On exit:      --
1101 ;
1102 ; Use:          Called when the user clicks on the tear icon
1103
1104 tms__tearMenu   ROUT
1105
1106                 STMFD   R13!,{R0-R2,R4,R14}     ;Stack some registers
1107                 LDR     R0,[R10,#hFlags]        ;Get the menu flags
1108                 ORR     R0,R0,#hFlag__torn      ;The menu is now torn
1109                 STR     R0,[R10,#hFlags]        ;Store back the flags
1110                 LDR     R0,[R10,#hPrevMenu]     ;Get the previous menu
1111                 CMP     R0,#0                   ;Is there one?
1112                 BLNE    tms__deselect           ;Yes -- deselect it
1113
1114                 ; --- Start the drag operaton ---
1115
1116                 SUB     R13,R13,#28             ;Get me a block
1117                 LDR     R0,[R10,#hHandle]       ;Get the window handle
1118                 MOV     R1,#1                   ;Drag window position
1119                 STMIA   R13,{R0,R1}             ;Store them in the block
1120                 MOV     R1,R13                  ;Point to the block
1121                 SWI     Wimp_DragBox            ;Start the drag
1122                 ADD     R13,R13,#28             ;Get the stack back
1123
1124                 ; --- Alter the icons on the bar ---
1125
1126                 BL      tms__updateBar          ;Update the bar
1127
1128                 ; --- Add the menu to the list of torn menus ---
1129
1130 10tms__tearMenu LDR     R0,tms__tornoffs        ;Get the list head
1131                 STR     R0,[R10,#hNextTorn]     ;Put pointer in menu header
1132                 STR     R10,tms__tornoffs       ;Store this as the head
1133                 LDR     R0,tms__current         ;Get the current transient
1134                 CMP     R0,R10                  ;Are we tearing it?
1135                 BNE     %15tms__tearMenu        ;No -- jump ahead
1136                 MOV     R0,#0                   ;A NULL pointer
1137                 STR     R0,tms__current         ;No current transient
1138                 BL      tearSupport_closed      ;TearoffSupt_Closed
1139
1140                 ; --- Close the transient if we need to ---
1141
1142 15tms__tearMenu LDR     R0,tms__flags           ;Get the program flags
1143                 TST     R0,#tFlag__close        ;Do we close transients?
1144                 LDRNE   R2,tms__current         ;Point to current transient
1145                 BLNE    tms__closeMenu          ;And close the transient
1146
1147                 ; --- Return to the caller ---
1148
1149                 LDMFD   R13!,{R0-R2,R4,PC}^     ;Return to caller
1150
1151                 LTORG
1152
1153 ; --- tms__unTearMenu ---
1154 ;
1155 ; On entry:     R10 == pointer to menu to untear
1156 ;
1157 ; On exit:      --
1158 ;
1159 ; Use:          'Un-tears' the give menu. Note that the bar is NOT redrawn
1160
1161 tms__unTearMenu ROUT
1162
1163                 STMFD   R13!,{R0-R2,R14}        ;Stack some registers
1164                 LDR     R0,tms__tornoffs        ;Get the torn off list
1165                 MOV     R1,#0                   ;The previous menu
1166 00              CMP     R0,R10                  ;Is this the menu
1167                 BEQ     %10tms__unTearMenu      ;Yes -- deal with it
1168                 MOV     R1,R0                   ;This is now the previous
1169                 LDR     R0,[R0,#hNextTorn]      ;Get the next in the list
1170                 CMP     R0,#0                   ;Is there one?
1171                 BNE     %00tms__unTearMenu      ;Yes -- deal with it
1172
1173                 ; --- Cant find it, werg! ---
1174
1175                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1176
1177                 ; -- Right, we've found it now ---
1178
1179 10              LDR     R2,[R0,#hNextTorn]      ;Get the pointer to next
1180                 CMP     R1,#0                   ;Is it the first in list?
1181                 STREQ   R2,tms__tornoffs        ;Yes -- store next as head
1182                 STRNE   R2,[R1,#hNextTorn]      ;No -- store in prev ptr
1183                 LDR     R0,[R10,#hFlags]        ;Get the menu flags
1184                 BIC     R0,R0,#hFlag__torn      ;We are not torn now
1185                 STR     R0,[R10,#hFlags]        ;Store the flags back
1186                 TST     R0,#hFlag__warned       ;Have we been warned?
1187                 BEQ     %15tms__unTearMenu      ;No -- jump ahead
1188                 LDR     R2,[R10,#hSubMenu]      ;Get the sub menu
1189                 BL      tms__closeMenu          ;Close it
1190                 MOV     R0,R10                  ;Point to my menu
1191                 BL      tms__deselect           ;Deselect it
1192
1193                 ; --- Unfold the menu if we need to ---
1194
1195 15              LDR     R0,[R10,#hFlags]        ;Get the menu flags
1196                 TST     R0,#hFlag__folded       ;Is the menu folded
1197                 BLNE    tms__foldMenu           ;Yes -- unfold it
1198
1199                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1200
1201                 LTORG
1202
1203 ; --- tms__closeTornMenu ---
1204 ;
1205 ; On entry:     R10 == pointer to torn off menu to close
1206 ;
1207 ; On exit:      --
1208 ;
1209 ; Use:          Closes a torn off menu.
1210
1211 tms__closeTornMenu ROUT
1212
1213                 STMFD   R13!,{R0-R2,R14}        ;Stack some registers
1214
1215                 BL      tms__unTearMenu         ;'Un-tear' the menu
1216                 MOV     R2,R10                  ;Close this menu
1217                 BL      tms__closeMenu          ;Now close the menu
1218                 LDR     R0,tms__flags           ;Get the program flags
1219                 TST     R0,#tFlag__close        ;Do we close transients?
1220                 LDRNE   R2,tms__current         ;Point to current transient
1221                 BLNE    tms__closeMenu          ;And close the transient
1222
1223                 ; --- Return to the caller ---
1224
1225                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1226
1227                 LTORG
1228
1229 ; --- tms__locateMenu ---
1230 ;
1231 ; On entry:     R4 == pointer to menu to find
1232 ;
1233 ; On exit:      R4 preserved if it exists, 0 otherwise
1234 ;
1235 ; Use:          Attempt to find the given menu in the torn off
1236 ;               list. It is returned in R4 if it is found
1237
1238 tms__locateMenu ROUT
1239
1240                 STMFD   R13!,{R14}              ;Stack some registers
1241                 LDR     R14,tms__tornoffs       ;Get the torn off list
1242                 CMP     R14,#0                  ;Are there any
1243                 BEQ     %99tms__locateMenu      ;No -- return failure
1244 00              CMP     R14,R4                  ;Have we found it?
1245                 LDMEQFD R13!,{PC}^              ;Yes -- return
1246                 LDR     R14,[R14,#hNextTorn]    ;Get the next in the list
1247                 CMP     R14,#0                  ;Is there one
1248                 BNE     %00tms__locateMenu      ;Yes -- try it
1249
1250                 ; --- We didn't find it ---
1251
1252 99              MOV     R4,#0                   ;Return failure
1253                 LDMFD   R13!,{PC}^              ;Return to caller
1254
1255                 LTORG
1256
1257 ; --- tms__searchForMenu ---
1258 ;
1259 ; On entry:     R0 == pointer to packed definition
1260 ;               R1 == pointer to event handler
1261 ;               R2 == R10 value passed to handler
1262 ;               R3 == R12 value passed to handler
1263 ;
1264 ; On exit:      C set and R4 points to menu if found, C clear otherwise
1265 ;
1266 ; Use:          Searches the tornoff menus for a menu with characteristics
1267 ;               matching the search required
1268
1269 tms__searchForMenu ROUT
1270
1271                 BIC     R14,R14,#C_flag         ;We haven't found it
1272                 STMFD   R13!,{R5-R7,R12,R14}    ;Stack some registers
1273                 WSPACE  tms__wSpace             ;Locate my workspace
1274                 LDR     R14,tms__tornoffs       ;Get the torn off list
1275                 CMP     R14,#0                  ;Are there any
1276                 BEQ     %99tms__searchForMenu   ;No -- return failure
1277 00              ADD     R4,R14,#hHandler        ;Point to useful values
1278                 LDMIA   R4,{R4-R7}              ;Get them out
1279                 CMP     R0,R7                   ;Packed definition the same?
1280                 CMPEQ   R1,R4                   ;...and the handler?
1281                 CMPEQ   R2,R5                   ;...and R10 value?
1282                 CMPEQ   R3,R6                   ;...and R12 value?
1283                 MOVEQ   R4,R14                  ;We've found it
1284                 LDMEQFD R13!,{R5-R7,R12,R14}    ;Get back registers
1285                 ORREQS  PC,R14,#C_flag          ;And return happy
1286                 LDR     R14,[R14,#hNextTorn]    ;Get the next in the list
1287                 CMP     R14,#0                  ;Is there one
1288                 BNE     %00tms__searchForMenu   ;Yes -- try it
1289
1290                 ; --- We didn't find it ---
1291
1292 99              MOV     R4,#0                   ;Return failure
1293                 LDMFD   R13!,{R5-R7,R12,PC}^    ;Return to caller
1294
1295                 LTORG
1296
1297 ; --- tms_closeMenu ---
1298 ;
1299 ; On entry:     R0 == pointer to menu definition
1300 ;               R1 == pointer to event handler
1301 ;               R2 == R10 value to look for
1302 ;               R3 == R12 value to look for
1303 ;
1304 ; On exit:      --
1305 ;
1306 ; Use:          Searches through the menus which have been torn off for a
1307 ;               menu which matches the specifications given, and closes
1308 ;               it if it is found.
1309
1310                 EXPORT  tms_closeMenu
1311 tms_closeMenu   ROUT
1312
1313                 STMFD   R13!,{R4,R10,R12,R14}   ;Stack registers
1314                 WSPACE  tms__wSpace             ;Locate my workspace
1315                 BL      tms__searchForMenu      ;Try to find the menu
1316                 MOVCS   R10,R4                  ;Found it -- put in R10
1317                 BLCS    tms__closeTornMenu      ;And close it
1318                 LDMFD   R13!,{R4,R10,R12,PC}^   ;Return to caller
1319                 
1320                 LTORG
1321
1322 ; --- tms_closeAll ---
1323 ;
1324 ; On entry:     R0 == R10 value to search for
1325 ;
1326 ; On exit:      --
1327 ;
1328 ; Use:          Closes all the torn off menus with the given r10
1329 ;               value.
1330
1331                 EXPORT  tms_closeAll
1332 tms_closeAll    ROUT
1333
1334                 STMFD   R13!,{R10,R12,R14}      ;Stack registers
1335                 WSPACE  tms__wSpace             ;Locate my workspace
1336                 LDR     R10,tms__tornoffs       ;Get the torn off list
1337                 CMP     R10,#0                  ;Are there any
1338                 BEQ     %90tms_closeAll         ;No -- return
1339 00              LDR     R14,[R10,#hR10]         ;Get the R10 value
1340                 CMP     R0,R14                  ;Is R10 value the same?
1341                 BLEQ    tms__closeTornMenu      ;Yes -- close that menu
1342                 LDR     R10,[R10,#hNextTorn]    ;Get the next in the list
1343                 CMP     R10,#0                  ;Is there one
1344                 BNE     %00tms_closeAll         ;Yes -- try it
1345
1346 90tms_closeAll  LDMFD   R13!,{R10,R12,PC}^      ;Return to caller
1347
1348                 LTORG   
1349
1350 ; --- tms__foldMenu ---
1351 ;
1352 ; On entry:     R10 == pointer to menu to fold
1353 ;
1354 ; On exit:      --
1355 ;
1356 ; Use:          Folds or unfolds the menu, as appropriate
1357
1358 tms__foldMenu   ROUT
1359
1360                 STMFD   R13!,{R0-R5,R14}        ;Stack some registers
1361
1362                 ; --- Get the window state ---
1363
1364                 SUB     R13,R13,#88             ;Get me a block
1365                 LDR     R0,[R10,#hHandle]       ;Get the window handle
1366                 STR     R0,[R13,#0]             ;Store it in the block
1367                 MOV     R1,R13                  ;Point to the block
1368                 SWI     Wimp_GetWindowState     ;Get the window state
1369
1370                 ; --- First, close the current transient menu ---
1371
1372                 LDR     R0,tms__flags           ;Get the program flags
1373                 TST     R0,#tFlag__close        ;Do we close transients?
1374                 LDRNE   R2,tms__current         ;Point to current transient
1375                 BLNE    tms__closeMenu          ;And close the transient
1376
1377                 LDR     R0,[R10,#hFlags]        ;Get the menu flags
1378                 EOR     R0,R0,#hFlag__folded    ;Toggle the foldedness
1379                 STR     R0,[R10,#hFlags]        ;Store back modified flags
1380                 TST     R0,#hFlag__folded       ;Test that bit now
1381                 BEQ     %50tms__foldMenu        ;No longer folded -- jump
1382
1383                 ; --- We must now fold up the menu ---
1384
1385                 TST     R0,#hFlag__scrBar       ;Is there a scroll bar?
1386                 BEQ     %25tms__foldMenu        ;No -- do quick fold
1387
1388                 ADD     R1,R10,#hHandle         ;Point to the window handle
1389                 SWI     Wimp_CloseWindow        ;Close the window
1390                 SWI     Wimp_DeleteWindow       ;And then delete it
1391                 LDR     R0,[R10,#hHandle]       ;The window handle
1392                 ADRL    R1,tms__eventHandler    ;Point to the handler
1393                 MOV     R2,R10                  ;The handle passed
1394                 MOV     R3,R12                  ;Workspace passed in R3
1395                 BL      win_removeEventHandler  ;Remove the event handler
1396                 LDR     R1,tms__oldHandle       ;Get the old handle
1397                 CMP     R0,R1                   ;Are they the same?
1398                 BLEQ    tms__cleanUp            ;Yes -- clean up a bit
1399                 LDR     R0,[R10,#hHeight]       ;Get the menu height
1400                 BL      tms__createWindow       ;Create the window
1401                 MOVVS   R1,#1                   ;On error -- show 1 icon
1402                 BLVS    errorBox                ;...display the error
1403                 BVS     %99tms__foldMenu        ;...and return to caller
1404                 ADRL    R1,tms__eventHandler    ;Point to the handler
1405                 MOV     R2,R10                  ;The handle passed
1406                 MOV     R3,R12                  ;Workspace passed in R3
1407                 BL      win_eventHandler        ;Remove the event handler
1408                 MOV     R1,R13                  ;Point to window state
1409                 STR     R0,[R1,#0]              ;Store in the block
1410                 LDR     R4,[R1,#16]             ;Get y1
1411                 SUB     R0,R4,#24               ;No -- y0-y1-actual height
1412                 STR     R0,[R1,#8]              ;Store new y0
1413                 BL      tspr_adjustBox          ;Mangle to fit on the screen
1414                 SWI     Wimp_OpenWindow         ;Open the window
1415                 B       %99tms__foldMenu        ;Return to caller
1416
1417                 ; --- The menu has no scrollbar ---
1418
1419 25tms__foldMenu MOV     R1,R13                  ;Point to state
1420                 LDR     R0,[R1,#16]             ;Get y1
1421                 SUB     R0,R0,#24               ;New y0 value
1422                 STR     R0,[R1,#8]              ;Store it in the block
1423                 SWI     Wimp_OpenWindow         ;Open the window
1424                 B       %99tms__foldMenu        ;And return
1425
1426                 ; --- The menu must be 'un-folded' ---
1427
1428 50tms__foldMenu BL      screen_getInfo          ;Get the screen information
1429                 LDR     R1,[R0,#screen_height]  ;Get the screen height
1430                 LDR     R2,[R10,#hMaxHeight]    ;Get the maximum menu height
1431                 LDR     R3,[R10,#hHeight]       ;And the actual menu height
1432
1433                 ; --- We add a scroll bar if h>maxH or h+50>screen height ---
1434
1435                 CMP     R2,#0                   ;Is there a maximum height?
1436                 BEQ     %55tms__foldMenu        ;No try next condition
1437                 CMP     R3,R2                   ;Is height > maxHeight?
1438                 BGT     %60tms__foldMenu        ;Yes -- unfold with scrll bar
1439 55tms__foldMenu ADD     R3,R3,#50               ;Add a little to the height
1440                 CMP     R3,R1                   ;Compare to the screen height
1441                 BLE     %75tms__foldMenu        ;Unfold without scroll bar
1442
1443                 ; --- Unfold with a scroll bar ---
1444
1445 60tms__foldMenu ADD     R1,R10,#hHandle         ;Point to the window handle
1446                 SWI     Wimp_CloseWindow        ;Close the window
1447                 SWI     Wimp_DeleteWindow       ;And then delete it
1448                 LDR     R0,[R10,#hHandle]       ;The window handle
1449                 ADRL    R1,tms__eventHandler    ;Point to the handler
1450                 MOV     R2,R10                  ;The handle passed
1451                 MOV     R3,R12                  ;Workspace passed in R3
1452                 BL      win_removeEventHandler  ;Remove the event handler
1453                 LDR     R1,tms__oldHandle       ;Get the old handle
1454                 CMP     R0,R1                   ;Are they the same?
1455                 BLEQ    tms__cleanUp            ;Yes -- clean up a bit
1456                 LDR     R0,[R10,#hHeight]       ;Get the menu height
1457                 BL      tms__createWindow       ;Create the window
1458                 MOVVS   R1,#1                   ;On error -- show 1 icon
1459                 BLVS    errorBox                ;...display the error
1460                 BVS     %99tms__foldMenu        ;...and return to caller
1461                 ADRL    R1,tms__eventHandler    ;Point to the handler
1462                 MOV     R2,R10                  ;The handle passed
1463                 MOV     R3,R12                  ;Workspace passed in R3
1464                 BL      win_eventHandler        ;Remove the event handler
1465                 MOV     R1,R13                  ;Point to window state
1466                 STR     R0,[R1,#0]              ;Store in the block
1467                 LDR     R4,[R1,#16]             ;Get y1
1468                 LDR     R3,[R10,#hHeight]       ;And actual height
1469                 LDR     R2,[R10,#hMaxHeight]    ;Get the maximum height
1470                 CMP     R2,#0                   ;Is there one?
1471                 SUBNE   R0,R4,R2                ;Yes -- y0=y1-maxHeight
1472                 SUBEQ   R0,R4,R3                ;No -- y0-y1-actual height
1473                 STR     R0,[R1,#8]              ;Store new y0
1474                 BL      tspr_adjustBox          ;Mangle to fit on the screen
1475                 MOV     R14,#-1                 ;To open at the front
1476                 STR     R14,[R1,#28]            ;We alter the behind value
1477                 SWI     Wimp_OpenWindow         ;Open the window
1478                 B       %99tms__foldMenu        ;Return to caller
1479
1480                 ; --- We must unfold without a scroll bar ---
1481
1482 75tms__foldMenu MOV     R1,R13                  ;Point to state
1483                 LDR     R0,[R1,#16]             ;Get y1
1484                 LDR     R2,[R10,#hHeight]       ;Get actual height
1485                 SUB     R0,R0,R2                ;New y0 value
1486                 STR     R0,[R1,#8]              ;Store it in the block  
1487                 MOV     R14,#-1                 ;To open at the front
1488                 STR     R14,[R1,#28]            ;We alter the behind value
1489                 SWI     Wimp_OpenWindow         ;Open the window
1490
1491 99tms__foldMenu ADD     R13,R13,#88             ;Get the block back
1492                 LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
1493
1494 ; --- tms__ensureWindowOK ---
1495 ;
1496 ; On entry:     R1 == pointer to window state
1497 ;               R10 == ponter to the menu
1498 ;
1499 ; On exit:      --
1500 ;
1501 ; Use:          Called after a mode change, to make sure that the menu still
1502 ;               fits on the screen, and to make appropriate changes
1503 ;               if the font has changed, etc.
1504
1505 tms__ensureWindowOK ROUT
1506
1507                 STMFD   R13!,{R0-R4,R14}        ;Stack some registers
1508
1509                 LDR     R0,[R10,#hFlags]        ;Get the menu flags
1510                 TST     R0,#hFlag__folded       ;Is the menu folded
1511                 BNE     %98tms__ensureWindowOK  ;Yes -- return
1512                 BL      screen_getInfo          ;Get the screen info
1513                 LDR     R4,[R0,#screen_height]  ;Get screen height
1514                 LDR     R3,[R10,#hHeight]       ;Get menu height
1515                 ADD     R3,R3,#50               ;Add 50 for luck
1516                 LDR     R2,[R10,#hFlags]        ;Get the menu flags
1517
1518                 ; --- Check to see if we should remove scroll bar ---
1519
1520                 TST     R2,#hFlag__scrBar       ;Is there a scroll bar
1521                 BEQ     %40tms__ensureWindowOK  ;No -- jump ahead
1522                 CMP     R3,R4                   ;Is actual < screen height?
1523                 BGT     %40tms__ensureWindowOK  ;No -- jump ahead
1524                 LDR     R14,[R10,#hMaxHeight]   ;Get max height
1525                 CMP     R14,#0                  ;Is there one?
1526                 BEQ     %10tms__ensureWindowOK  ;No -- remove scroll bar
1527                 CMP     R3,R14                  ;Is actual < max height?
1528                 BGT     %40tms__ensureWindowOK  ;No -- jump ahead
1529
1530                 ; --- Remove the scroll bar then ---
1531
1532 10              BL      %80tms__ensureWindowOK  ;Create a new window
1533                 LDR     R0,[R1,#8]              ;Get y0
1534                 ADD     R0,R0,R3                ;Calculate y1
1535                 STR     R0,[R1,#16]             ;Store it in the block
1536                 SWI     Wimp_OpenWindow         ;Open the window
1537                 B       %99tms__ensureWindowOK  ;And return to caller
1538
1539                 ; --- Check if we should add a scroll bar ---
1540
1541 40              TST     R2,#hFlag__scrBar       ;Is there a scroll bar
1542                 BNE     %98tms__ensureWindowOK  ;Yes -- return
1543                 CMP     R3,R4                   ;Is actual > screen height?
1544                 BLT     %98tms__ensureWindowOK  ;No -- return
1545
1546                 ; --- Rebuild the window ---
1547
1548 50              BL      %80tms__ensureWindowOK  ;Create a new window
1549                 LDR     R0,[R1,#4]              ;Get old x0
1550                 LDR     R2,[R10,#hTotWidth]     ;Get the menu width
1551                 ADD     R0,R0,R2                ;Calculate x1
1552                 STR     R0,[R1,#12]             ;Store it in the block
1553                 SWI     Wimp_OpenWindow         ;Open the window
1554                 BL      tms__width              ;Check the width
1555                 B       %99tms__ensureWindowOK  ;And return to caller
1556
1557                 ; --- Create a new window ---
1558
1559 80              STMFD   R13!,{R1-R3,R14}        ;Save some registers
1560
1561                 ADD     R1,R10,#hHandle         ;Point to the window handle
1562                 SWI     Wimp_CloseWindow        ;Close the window
1563                 SWI     Wimp_DeleteWindow       ;And then delete it
1564                 LDR     R0,[R10,#hHandle]       ;The window handle
1565                 ADRL    R1,tms__eventHandler    ;Point to the handler
1566                 MOV     R2,R10                  ;The handle passed
1567                 MOV     R3,R12                  ;Workspace passed in R3
1568                 BL      win_removeEventHandler  ;Remove the event handler
1569                 LDR     R1,tms__oldHandle       ;Get the old handle
1570                 CMP     R0,R1                   ;Are they the same?
1571                 BLEQ    tms__cleanUp            ;Yes -- clean up a bit
1572                 LDR     R0,[R10,#hHeight]       ;Get the menu height
1573                 BL      tms__createWindow       ;Create the window
1574                 MOVVS   R1,#1                   ;On error -- show 1 icon
1575                 BLVS    errorBox                ;...display the error
1576                 BVS     %99tms__ensureWindowOK  ;...and return to caller
1577                 ADRL    R1,tms__eventHandler    ;Point to the handler
1578                 MOV     R2,R10                  ;The handle passed
1579                 MOV     R3,R12                  ;Workspace passed in R3
1580                 BL      win_eventHandler        ;Remove the event handler
1581                 LDMFD   R13!,{R1-R3,R14}        ;Get registers back
1582                 STR     R0,[R1,#0]              ;Store in the block
1583                 MOV     R0,#-1                  ;The behind value
1584                 STR     R0,[R1,#28]             ;Store in the block
1585
1586                 MOVS    PC,R14                  ;Return to caller
1587
1588                 ; --- Return to caller ---
1589
1590 98              MOV     R0,#-1                  ;Open in front
1591                 STR     R0,[R1,#28]             ;Store this fact
1592                 SWI     Wimp_OpenWindow         ;Open the window
1593                 LDR     R14,tms__flags          ;Get the main flags word
1594                 TST     R14,#tFlag__newFont     ;Has the font changed?
1595                 BL      tms__width              ;Yes -- check the width
1596
1597 99              LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
1598
1599                 LTORG
1600
1601 ; --- tms__idleHandler ---
1602 ;
1603 ; On entry:     R10 == pointer to menu
1604 ;
1605 ; On exit:      --
1606 ;
1607 ; Use:          Called on NULL events. R10 points to the menu that the
1608 ;               pointer is currently over
1609
1610 tms__idleHandler ROUT
1611
1612                 STMFD   R13!,{R1,R14}           ;Stack some registers
1613                 LDR     R1,tms__flags           ;Get the flags word
1614                 TST     R1,#tFlag__doFake       ;Are we about to fake a NULL?
1615                 LDMNEFD R13!,{R1,PC}^           ;Yes -- return then
1616                 TST     R1,#tFlag__faking       ;Are we fakingone now?
1617                 BNE     %10tms__idleHandler     ;Yes -- jump ahead then
1618                 SUB     R13,R13,#20             ;Get a block
1619                 MOV     R1,R13                  ;Point to the block
1620                 SWI     Wimp_GetPointerInfo     ;Get the pointer position
1621                 MOV     R14,#0                  ;Clear the button state
1622                 STR     R14,[R1,#8]             ;Put value in the bbits
1623                 BL      tms__buttons            ;Call the buttons routine
1624                 ADD     R13,R13,#20             ;Get the stack back
1625                 LDMFD   R13!,{R1,PC}^           ;Return to caller
1626
1627                 ; --- Clear the 'faking' bit ---
1628
1629 10              BIC     R1,R1,#tFlag__faking    ;Clear the flag
1630                 STR     R1,tms__flags           ;Store the new flags
1631                 LDMFD   R13!,{R1,PC}^           ;Return to caller
1632
1633                 LTORG
1634
1635 ; --- tms__makeDashPattern ---
1636 ;
1637 ; On entry:     --
1638 ;
1639 ; On exit:      --
1640 ;
1641 ; Use:          Programs the VDU dot pattern, for sheer prettiness.
1642
1643 tms__makeDashPattern ROUT
1644
1645                 STMFD   R13!,{R0-R2,R14}        ;Stack some registers
1646                 MOV     R0,#163                 ;General OS_Byte
1647                 MOV     R1,#242                 ;242 is the only valid value
1648                 MOV     R2,#8                   ;Repeat length
1649                 SWI     OS_Byte                 ;Set dash pattern length
1650
1651                 ADR     R0,tms__dashPtn         ;Point to the pattern spec
1652                 MOV     R1,#?tms__dashPtn       ;Size of the string
1653                 SWI     OS_WriteN               ;Write 'em all to VDU drivers
1654                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1655
1656 tms__dashPtn    DCB     23,6,&f0,&f0,&f0,&f0,&f0,&f0,&f0,&f0
1657
1658                 LTORG
1659
1660 ; --- tms__redrawTick ---
1661 ;
1662 ; On entry:     R4 == the y coordinate
1663 ;               R11 == item flags
1664 ;               R13 == pointer to a block to use
1665 ;
1666 ; On exit:      --
1667 ;
1668 ; Use:          Redraw the tick/splodge on the left hand side of a menu
1669
1670 tms__redrawTick ROUT
1671
1672                 STMFD   R13!,{R0-R3,R5,R14}     ;Stack the link
1673                 ADD     R5,R13,#24              ;Point to the block
1674                 MOV     R0,#0                   ;x0
1675                 MOV     R2,#24                  ;x1
1676                 SUB     R1,R4,#44               ;y0
1677                 MOV     R3,R4                   ;y1
1678                 STMIA   R5!,{R0-R3}             ;Store this in the block
1679                 LDR     R0,=&07000038           ;Icon flags so far
1680
1681                 TST     R11,#iFlag__ticked      ;Is there a tick
1682                 TSTEQ   R11,#iFlag__radio       ;Or a splodge?
1683                 MOVEQ   R1,#&20                 ;Neither -- plot nothing
1684                 BEQ     %00tms__redrawTick      ;And plot it
1685
1686                 TST     R11,#iFlag__shaded      ;Is the item shaded?
1687                 ORRNE   R0,R0,#&00400000        ;Yes -- shade icon
1688                 TST     R11,#iFlag__ticked      ;Are we plotting a tick?
1689                 MOVEQ   R1,#&8F                 ;Nope -- must be a splodge
1690                 BEQ     %00tms__redrawTick      ;And plot it
1691                 LDR     R1,tms__flags           ;Get the flags word
1692                 TST     R1,#tFlag__riscos3      ;Is this RISC OS 3?
1693                 BNE     %01tms__redrawTick      ;Yes -- jump a bit
1694                 MOV     R1,#&80                 ;No -- plot a tick
1695
1696 00              ORR     R0,R0,#1                ;Text icon
1697                 STMIA   R5,{R0,R1}              ;Fill in the rest of block
1698                 B       %02tms__redrawTick      ;And jump this bit
1699
1700                 ; --- Plot tick RISCOS 3 style ---
1701
1702 01              MOV     R2,#1                   ;Point R2 at it
1703                 ORR     R0,R0,#&100             ;Indirected icon
1704                 ORR     R0,R0,#&2               ;Sprite icon
1705                 ADR     R1,tms__sprTickName     ;Point to the sprite name
1706                 MOV     R3,#2                   ;The buffer length
1707                 STMIA   R5,{R0-R3}              ;Fill in the rest of block
1708
1709 02              ADD     R1,R13,#24              ;Point to the block
1710                 SWI     Wimp_PlotIcon           ;Plot the icon
1711
1712                 LDMFD   R13!,{R0-R3,R5,PC}^     ;Return to caller
1713
1714                 LTORG
1715
1716 tms__sprTickName DCB    &80,0
1717
1718                 EXPORT  tms__wSpace
1719 tms__wSpace     DCD     0
1720
1721 ; --- tms__redrawSprite ---
1722 ;
1723 ; On entry:     R4 == the y coordinate
1724 ;               R11 == item flags
1725 ;               R13 == pointer to a block to use
1726 ;
1727 ; On exit:      --
1728 ;
1729 ; Use:          Redraw the tick/splodge on the left hand side of a menu
1730
1731 tms__redrawSprite ROUT
1732
1733                 STMFD   R13!,{R0-R3,R5,R14}     ;Stack the link
1734                 ADD     R5,R13,#24              ;Point to the block
1735                 MOV     R0,#24+8                ;x0
1736                 LDR     R2,[R10,#hSprWidth]     ;Get maximum sprite width
1737                 ADD     R2,R2,R0                ;Add on to get x1
1738                 SUB     R1,R4,#44               ;y0
1739                 MOV     R3,R4                   ;y1
1740                 STMIA   R5!,{R0-R3}             ;Store this in the block
1741                 LDR     R0,=&07000112           ;Icon flags so far
1742                 TST     R11,#iFlag__sprite      ;Is there a sprite?
1743                 BICEQ   R0,R0,#2                ;No -- plot no sprite then
1744
1745                 TST     R11,#iFlag__shaded      ;Is the item shaded?
1746                 ORRNE   R0,R0,#&00400000        ;Yes -- shade icon
1747                 TST     R11,#iFlag__halfSize    ;Is it a small one?
1748                 ORRNE   R0,R0,#&00000800        ;Yes -- set the half-size bit
1749                 STR     R0,[R5],#4              ;Stash the flags away
1750
1751                 LDR     R0,[R7,#iSprName]       ;Find the sprite name string
1752                 LDR     R1,[R7,#iSprArea]       ;Get the sprite area too
1753                 MOV     R2,#1                   ;Not a number, it's a name
1754                 STMIA   R5!,{R0-R2}             ;Stash the data away too
1755
1756 02              ADD     R1,R13,#24              ;Point to the block
1757                 SWI     Wimp_PlotIcon           ;Plot the icon
1758
1759                 LDMFD   R13!,{R0-R3,R5,PC}^     ;Return to caller
1760
1761                 LTORG
1762
1763 ; --- tms__redrawText ---
1764 ;
1765 ; On entry:     R4 == the y coordinate
1766 ;               R7 == pointer to the icon
1767 ;               R10 == the menu pointer
1768 ;               R11 == item flags
1769 ;               R13 == pointer to a block to use
1770 ;
1771 ; On exit:      --
1772 ;
1773 ; Use:          Redraw the text part of the menu
1774
1775 tms__redrawText ROUT
1776
1777                 STMFD   R13!,{R0-R3,R14}        ;Stack the link
1778
1779                 ADD     R14,R13,#20             ;Point to the block
1780
1781                 ; --- Plot a dirty great bar across the item ---
1782
1783                 MOV     R0,#24                  ;x0
1784                 LDR     R2,[R10,#hTotWidth]     ;The menu width
1785                 SUB     R2,R2,#24               ;Calculate x1
1786                 SUB     R1,R4,#44               ;y0
1787                 MOV     R3,R4                   ;y1
1788                 STMIA   R14!,{R0-R3}            ;Store this in the block
1789                 LDR     R0,=&07000030           ;Get some base flags
1790                 TST     R11,#iFlag__shaded      ;Is the item shaded?
1791                 ORRNE   R0,R0,#&00400000        ;Yes -- set the shaded bitty
1792                 LDREQ   R2,[R10,#hSelected]     ;Get the selected item
1793                 CMPEQ   R7,R2                   ;Is it this item?
1794                 EOREQ   R0,R0,#&77000000        ;Yes -- invert it then
1795                 STR     R0,[R14],#4             ;Save these flags away
1796                 ADD     R1,R13,#20              ;Point to the block
1797                 SWI     Wimp_PlotIcon           ;Plot the icon
1798
1799                 ; --- Now plot the text transparently over this ---
1800
1801                 LDR     R14,[R10,#hSprWidth]    ;Load sprite column width
1802                 ADD     R14,R14,#24             ;Bump in a little
1803                 STR     R14,[R1,#0]             ;Save as the x0 position
1804                 LDR     R0,=&07000131           ;The icon flags
1805                 TST     R11,#iFlag__shaded      ;Is the item shaded?
1806                 ORRNE   R0,R0,#&00400000        ;Yes -- shade icon
1807                 LDREQ   R2,[R10,#hSelected]     ;Get the selected item
1808                 CMPEQ   R7,R2                   ;Is it this item?
1809                 EOREQ   R0,R0,#&77000000        ;No -- use these colours
1810                 LDR     R1,[R7,#iText]          ;Point to the text
1811                 MOV     R2,#-1                  ;No validation string
1812                 MOV     R3,#&ff                 ;Buffer length
1813                 ADD     R14,R13,#36             ;Point to the right bit
1814                 STMIA   R14,{R0-R3}             ;Fill in the rest of block
1815                 ADD     R1,R13,#20              ;Point to the block
1816                 SWI     Wimp_PlotIcon           ;Plot the icon
1817
1818                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
1819
1820                 LTORG
1821
1822 ; --- tms__redrawKey ---
1823 ;
1824 ; On entry:     R4 == the y coordinate
1825 ;               R7 == pointer to the icon
1826 ;               R10 == the menu pointer
1827 ;               R11 == item flags
1828 ;               R13 == pointer to a block to use
1829 ;
1830 ; On exit:      --
1831 ;
1832 ; Use:          Redraw the text part of the menu
1833
1834 tms__redrawKey  ROUT
1835
1836                 STMFD   R13!,{R0-R3,R5,R11,R14} ;Stack the link
1837
1838                 ADD     R5,R13,#28              ;Point to the block
1839                 LDR     R2,[R7,#iKeyCode]       ;Get the string to print
1840                 CMP     R2,#-1                  ;Is there one?
1841                 BEQ     %99tms__redrawKey       ;No -- return
1842                 LDR     R2,[R10,#hTotWidth]     ;The menu width
1843                 LDR     R0,[R10,#hKeyWidth]     ;Get the shortcut width
1844                 SUB     R2,R2,#24               ;Calculate x1
1845                 SUB     R0,R2,R0                ;And then x0
1846                 SUB     R1,R4,#44               ;y0
1847                 MOV     R3,R4                   ;y1
1848                 STMIA   R5!,{R0-R3}             ;Store this in the block
1849                 LDR     R3,=&00000131           ;The icon flags
1850                 TST     R11,#iFlag__shaded      ;Is the item shaded?
1851                 ORRNE   R3,R3,#&007400000       ;Yes -- shade icon
1852                 BNE     %00tms__redrawKey       ;...forget this next bit
1853                 LDR     R2,[R10,#hSelected]     ;Get the selected item
1854                 CMP     R7,R2                   ;Is it this item?
1855                 ORRNE   R3,R3,#&07000000        ;No -- use these colours
1856                 ORREQ   R3,R3,#&70000000        ;Yep -- use these colours
1857 00              LDR     R0,[R7,#iKeyCode]       ;Point to the text
1858                 MOV     R1,#1                   ;Covert to a short string
1859                 LDR     R11,tms__R11            ;Get scratchpad address
1860                 BL      keyString               ;Do the conversion
1861                 MOV     R1,R0                   ;Put string in R1
1862                 MOV     R0,R3                   ;And flags in R0
1863                 MOV     R2,#-1                  ;No validation string
1864                 MOV     R3,#&ff                 ;Buffer length
1865                 STMIA   R5,{R0-R3}              ;Fill in the rest of block
1866                 ADD     R1,R13,#28              ;Point to the block
1867                 SWI     Wimp_PlotIcon           ;Plot the icon
1868
1869 99              LDMFD   R13!,{R0-R3,R5,R11,PC}^ ;Return to caller
1870
1871                 LTORG
1872
1873 ; --- tms__redrawArrow ---
1874 ;
1875 ; On entry:     R4 == the y coordinate
1876 ;               R10 == pointer to the menu
1877 ;               R11 == item flags
1878 ;               R13 == pointer to a block to use
1879 ;
1880 ; On exit:      --
1881 ;
1882 ; Use:          Redraw the arrow on the right hand side of a menu
1883
1884 tms__redrawArrow ROUT
1885
1886                 TST     R11,#iFlag__arrow       ;Is there an arrow?
1887                 MOVEQS  PC,R14                  ;No -- return
1888
1889                 STMFD   R13!,{R0-R3,R5,R14}     ;Stack the link
1890                 ADD     R5,R13,#24              ;Point to the block
1891                 LDR     R2,[R10,#hTotWidth]     ;x1
1892                 SUB     R0,R2,#24               ;x0
1893                 SUB     R1,R4,#44               ;y0
1894                 MOV     R3,R4                   ;y1
1895                 STMIA   R5!,{R0-R3}             ;Store this in the block
1896                 LDR     R0,=&07000038           ;Icon flags so far
1897                 TST     R11,#iFlag__shaded      ;Is the item shaded?
1898                 ORRNE   R0,R0,#&00400000        ;Yes -- shade icon
1899                 LDR     R1,tms__flags           ;Get the flags word
1900                 TST     R1,#tFlag__riscos3      ;Is this RISC OS 3?
1901                 BNE     %01tms__redrawArrow     ;Yes -- jump a bit
1902                 MOV     R1,#&89                 ;No -- plot a tick
1903                 ORR     R0,R0,#1                ;Text icon
1904                 STMIA   R5,{R0,R1}              ;Fill in the rest of block
1905                 B       %02tms__redrawArrow     ;And jump this bit
1906
1907                 ; --- Plot tick RISCOS 3 style ---
1908
1909 01              MOV     R2,#1                   ;The WIMP area
1910                 ORR     R0,R0,#&100             ;Indirected icon
1911                 ORR     R0,R0,#&2               ;Sprite icon
1912                 ADR     R1,tms__sprArrowName    ;Point to the sprite name
1913                 MOV     R3,#2                   ;The buffer length
1914                 STMIA   R5,{R0-R3}              ;Fill in the rest of block
1915
1916 02              ADD     R1,R13,#24              ;Point to the block
1917                 SWI     Wimp_PlotIcon           ;Plot the icon
1918
1919                 LDMFD   R13!,{R0-R3,R5,PC}^     ;Return to caller
1920
1921                 LTORG
1922
1923 tms__sprArrowName DCB &89,0
1924
1925 ; --- tms__redrawBar ---
1926 ;
1927 ; On entry:     R4 == the y coordinate
1928 ;               R10 == the menu pointer
1929 ;               R13 == pointer to a block to use
1930 ;
1931 ; On exit:      --
1932 ;
1933 ; Use:          Redraw the tearoff bar in a menu. Notice that this is
1934 ;               different to the steel version, which uses icons here
1935
1936 tms__redrawBar  ROUT
1937
1938                 STMFD   R13!,{R0-R3,R5,R14}     ;Stack the link
1939
1940                 ADD     R5,R13,#24              ;Point to the block
1941                 MOV     R0,#0                   ;x0
1942                 LDR     R2,[R10,#hTotWidth]     ;x1
1943                 MOV     R1,R4                   ;y0
1944                 MOV     R3,#0                   ;y1
1945                 STMIA   R5!,{R0-R3}             ;Store this in the block
1946                 LDR     R14,[R10,#hFlags]       ;Get the menu flags
1947                 LDR     R0,=&07000031           ;The icon flags
1948                 TST     R14,#hFlag__global      ;Is this a `global' menu?
1949                 ORREQ   R0,R0,#&30000000        ;No -- grey bar then
1950                 ORRNE   R0,R0,#&80000000        ;Yes -- blie bar then
1951                 MOV     R1,#0                   ;No text
1952                 STMIA   R5,{R0-R1}              ;Fill in the rest of block
1953                 ADD     R1,R13,#24              ;Point to the block
1954                 SWI     Wimp_PlotIcon           ;Plot the icon
1955                 LDR     R5,[R10,#hFlags]        ;Get the menu flags
1956                 TST     R5,#hFlag__torn         ;Has menu been torn?
1957                 BNE     %50tms__redrawBar       ;Yes -- draw that bit
1958
1959                 ; --- Draw just the tear icon ---
1960
1961                 ADD     R5,R13,#24              ;Point to the block
1962                 MOV     R0,#4                   ;x0
1963                 MOV     R2,#68                  ;x1
1964                 MOV     R1,#-20                 ;y0
1965                 MOV     R3,#-4                  ;y1
1966                 STMIA   R5!,{R0-R3}             ;Store this in the block
1967                 LDR     R0,=&00000112           ;The icon flags
1968                 MOV     R1,R0                   ;Hark -- R0 to be corrupted
1969                 BL      resspr_area             ;Get the sprite area
1970                 MOV     R2,R0                   ;Point R2 at it
1971                 MOV     R0,R1                   ;Get flags back in R0
1972                 ADR     R1,tms__sprTearName     ;Point to the sprite name
1973                 MOV     R3,#5                   ;The buffer length
1974                 STMIA   R5,{R0-R3}              ;Fill in the rest of block
1975
1976                 ADD     R1,R13,#24              ;Point to the block
1977                 SWI     Wimp_PlotIcon           ;Plot the icon
1978                 LDMFD   R13!,{R0-R3,R5,PC}^     ;Return to caller
1979
1980                 ; --- Plot the icons in a torn menu ---
1981
1982 50              ADD     R5,R13,#24              ;Point to the block
1983                 MOV     R0,#4                   ;x0
1984                 MOV     R2,#70                  ;x1
1985                 MOV     R1,#-20                 ;y0
1986                 MOV     R3,#-4                  ;y1
1987                 STMIA   R5!,{R0-R3}             ;Store this in the block
1988                 LDR     R0,=&00000112           ;The icon flags
1989                 MOV     R1,R0                   ;Hark -- R0 to be corrupted
1990                 BL      resspr_area             ;Get the sprite area
1991                 MOV     R2,R0                   ;Point R2 at it
1992                 MOV     R0,R1                   ;Get flags back in R0
1993                 ADR     R1,tms__sprCloseName    ;Point to the sprite name
1994                 MOV     R3,#6                   ;The buffer length
1995                 STMIA   R5,{R0-R3}              ;Fill in the rest of block
1996
1997                 ADD     R1,R13,#24              ;Point to the block
1998                 SWI     Wimp_PlotIcon           ;Plot the icon
1999
2000                 ADD     R5,R13,#24              ;Point to the block
2001                 LDR     R2,[R10,#hTotWidth]     ;Get the width
2002                 SUB     R0,R2,#60               ;x0
2003                 SUB     R2,R2,#4                ;x1
2004                 MOV     R1,#-20                 ;y0
2005                 MOV     R3,#-4                  ;y1
2006                 STMIA   R5!,{R0-R3}             ;Store this in the block
2007                 LDR     R0,=&00000112           ;The icon flags
2008                 MOV     R1,R0                   ;Hark -- R0 to be corrupted
2009                 BL      resspr_area             ;Get the sprite area
2010                 MOV     R2,R0                   ;Point R2 at it
2011                 MOV     R0,R1                   ;Get flags back in R0
2012                 ADR     R1,tms__sprFoldName     ;Point to the sprite name
2013                 MOV     R3,#6                   ;The buffer length
2014                 STMIA   R5,{R0-R3}              ;Fill in the rest of block
2015
2016                 ADD     R1,R13,#24              ;Point to the block
2017                 SWI     Wimp_PlotIcon           ;Plot the icon
2018
2019                 LDMFD   R13!,{R0-R3,R5,PC}^     ;Return to caller
2020
2021                 LTORG
2022
2023 tms__sprTearName DCB    "tear",0
2024 tms__sprCloseName DCB   "close",0
2025 tms__sprFoldName DCB    "fold",0
2026
2027 ; --- tms__doRedraw ---
2028 ;
2029 ; On entry:     R0 == flags:
2030 ;                     bit 0 == don't only plot queued items
2031 ;               R1 == pointer to the redraw block
2032 ;
2033 ; On exit:      --
2034 ;
2035 ; Use:          Actually redraws a menu, given the redraw block
2036
2037 tms__doRedraw   ROUT
2038
2039                 STMFD   R13!,{R0-R11,R14}       ;Stack some registers
2040                 MOV     R3,R0                   ;Keep flags safe nicely
2041
2042                 ; --- Set up some pointers ---
2043
2044                 SUB     R13,R13,#32             ;Get a nice block
2045                 MOV     R6,R1                   ;Remember the redraw block
2046                 LDR     R5,[R10,#hFlags]        ;Get the flags word
2047                 MOV     R4,#0                   ;The y coordinate
2048                 TST     R5,#hFlag__tearable     ;Is there a tearoff bar?
2049                 SUBNE   R4,R4,#tms__barHeight   ;Yes -- Allow for it
2050
2051                 ; --- Draw the tearoff bar ---
2052
2053                 TSTNE   R3,#1                   ;Does it need redrawing?
2054                 BLNE    tms__redrawBar          ;Yeap...
2055
2056                 ; --- Now deal with items ---
2057
2058                 LDR     R9,[R10,#hItems]        ;Point to the first item
2059 00tms__doRedraw LDR     R8,[R9,#iNumber]        ;Get the number of items
2060                 ADD     R7,R9,#iHdrSize         ;And point to the first item
2061
2062                 ; --- Now redraw each item ---
2063
2064 01tms__doRedraw LDR     R11,[R7,#iFlags]        ;Get the item flags
2065                 TST     R3,#1                   ;Are we only doing queued?
2066                 ORRNE   R11,R11,#&FF000000      ;No -- pretend it wa queued
2067
2068                 ; --- Redraw the tick/splodge on the left ---
2069
2070                 TST     R11,#iFlag__newTick     ;Has the tick changed?
2071                 BLNE    tms__redrawTick         ;Yes -- plot the tick thing
2072
2073                 ; --- Plot the main text part ---
2074
2075 09tms__doRedraw TST     R11,#iFlag__newText     ;Has the text changed?
2076                 BLNE    tms__redrawText         ;Yes -- redraw the text bit
2077
2078                 ; --- Now the sprite, if there is one ---
2079
2080 08tms__doRedraw TST     R11,#iFlag__newSpr      ;Does sprite need rendering?
2081                 BLNE    tms__redrawSprite       ;Yes -- render it then
2082
2083                 ; --- The keyboard shortcut ---
2084
2085                 TST     R11,#iFlag__newKey      ;Has shortcut changed?
2086                 BLNE    tms__redrawKey          ;Yes -- redraw it then
2087
2088                 ; --- The arrow ---
2089
2090                 TST     R11,#iFlag__newArrow    ;Has the arrow changed?
2091                 BLNE    tms__redrawArrow        ;Yes -- draw it then
2092
2093                 ; --- And finally, plot the dotted line ---
2094
2095                 TST     R11,#iFlag__dotted      ;Is there a dotted line here?
2096                 BEQ     %90tms__doRedraw        ;No -- jump this code then
2097                 MOV     R0,#4                   ;Move cursor
2098                 LDR     R1,[R6,#4]              ;To r.box->x0
2099                 LDR     R2,[R6,#16]             ;r.box->y1
2100                 ADD     R2,R2,R4                ;r.box->y1+y
2101                 SUB     R2,R2,#56               ;r.box->y1+y-(44+12)
2102                 LDR     R14,[R6,#24]            ;Don't neglect scroll offset
2103                 SUB     R2,R2,R14               ;No way bob...
2104                 SWI     OS_Plot                 ;Do the move
2105                 BL      tms__makeDashPattern    ;Program the dash pattern
2106                 MOV     R0,#7                   ;Colour 7
2107                 SWI     Wimp_SetColour          ;Thus let it be
2108                 MOV     R0,#17                  ;Dotted line -- both ends
2109                 LDR     R1,[R10,#hTotWidth]     ;Get the width to draw
2110                 MOV     R2,#0                   ;Relative y offset
2111                 SWI     OS_Plot                 ;Plot the line
2112
2113                 ; --- Alter the y coordinate ---
2114
2115 90tms__doRedraw TST     R11,#iFlag__dotted      ;Is there a dotted line
2116                 SUBNE   R4,R4,#68               ;Yes -- take into account
2117                 SUBEQ   R4,R4,#44               ;No -- just sub item height
2118
2119                 ; --- Do next item ---
2120
2121                 SUBS    R8,R8,#1                ;Decrement item count
2122                 ADDNE   R7,R7,#iItemSize        ;Point to the next item
2123                 BNE     %01tms__doRedraw        ;...and redraw it
2124                 LDR     R9,[R9,#iItems]         ;If at end -- point to next
2125                 CMP     R9,#0                   ;Any more items?
2126                 BNE     %00tms__doRedraw        ;Yes -- redraw them
2127                 ADD     R13,R13,#32             ;Get my block back
2128                 LDMFD   R13!,{R0-R11,PC}^       ;Return to caller
2129
2130                 LTORG
2131
2132 ; --- tms__redraw ---
2133 ;
2134 ; On entry:     R0 == event from wimp
2135 ;               R1 == pointer to the wimp block
2136 ;               R10 == pointer to the menu
2137 ;
2138 ; On exit:      --
2139 ;
2140 ; Use:          Called to perform the redraw loop when redrawing a menu
2141
2142 tms__redraw     ROUT
2143
2144                 STMFD   R13!,{R0,R1,R14}        ;Stack some registers
2145                 SWI     Wimp_RedrawWindow       ;Start the redraw
2146 00tms__redraw   CMP     R0,#0                   ;More to do?
2147                 LDMEQFD R13!,{R0,R1,PC}^        ;No -- return
2148                 MOV     R0,#1                   ;Redraw everything please
2149                 BL      tms__doRedraw           ;Perform the redrawing
2150                 SWI     Wimp_GetRectangle       ;Get another rectangle
2151                 B       %00tms__redraw          ;And keep redrawing
2152
2153                 LTORG
2154
2155 ; --- tms__update ---
2156 ;
2157 ; On entry:     R0 == flags (as for doRedraw)
2158 ;               R10 == pointer to the menu
2159 ;
2160 ; On exit:      --
2161 ;
2162 ; Use:          Updates the entire menu.
2163
2164                 EXPORT  tms__update
2165 tms__update     ROUT
2166
2167                 STMFD   R13!,{R0-R3,R14}        ;Stack some registers
2168
2169                 LDR     R14,[R10,#hHandle]      ;Load the window handle
2170                 STR     R14,[R13,#-44]!         ;Create a block
2171                 MOV     R0,#0                   ;Minimum x coord
2172                 LDR     R1,[R10,#hHeight]       ;Load out the height
2173                 RSB     R1,R1,#0                ;Minimum y coordinate
2174                 LDR     R2,[R10,#hTotWidth]     ;Get the total width
2175                 MOV     R3,#0                   ;Maximum y coordinate
2176                 STMIB   R13,{R0-R3}             ;Store in the block
2177                 MOV     R1,R13                  ;Point to the block
2178
2179                 SWI     Wimp_UpdateWindow       ;Start the redraw
2180 00tms__update   CMP     R0,#0                   ;More to do?
2181                 ADDEQ   R13,R13,#44             ;No -- get stack back
2182                 LDMEQFD R13!,{R0-R3,PC}^        ;...and return
2183                 LDR     R0,[R13,#44]            ;Load the caller's flags
2184                 BL      tms__doRedraw           ;Perform the redrawing
2185                 SWI     Wimp_GetRectangle       ;Get another rectangle
2186                 B       %00tms__update          ;And keep redrawing
2187
2188                 LTORG
2189
2190 ; --- tms__eventHandler ---
2191 ;
2192 ; On entry:     R0 == event, as returned from Wimp_Poll
2193 ;               R1 == pointer to the event block
2194 ;               R10 == pointer to the menu
2195 ;
2196 ; On exit:      --
2197 ;
2198 ; Use:          Deals with the event that has been sent to my window
2199
2200                 EXPORT tms__eventHandler
2201 tms__eventHandler ROUT
2202
2203                 ORR     R14,R14,#C_flag         ;Set carry flag on return
2204                 CMP     R0,#8                   ;Is it a low-numbered event?
2205                 ADDLE   PC,PC,R0,LSL #2         ;Yes -- dispatch
2206                 B       %00tms__eventHandler    ;No -- handle specially
2207
2208                 ; --- The event dispatch table ---
2209
2210                 BICS    PC,R14,#C_flag          ;Null events are ignored
2211                 B       tms__redraw             ;Call this to redraw menu
2212                 B       %10tms__eventHandler    ;Open unopened windows
2213                 B       %20tms__eventHandler    ;Close unclosed windows
2214                 B       %30tms__eventHandler    ;Pointer's left a window
2215                 B       %40tms__eventHandler    ;Gone back inside again
2216                 B       tms__buttons            ;Call the button handler
2217                 BICS    PC,R14,#C_flag          ;Drag returned -- so what
2218                 BICS    PC,R14,#C_flag          ;Key press
2219
2220                 ; --- Handle high-numbered events ---
2221
2222 00              CMP     R0,#17                  ;Is it a message?
2223                 CMPNE   R0,#18                  ;Or another message?
2224                 BICNES  PC,R14,#C_flag          ;No -- nothing we can do
2225
2226                 ; --- Deal with a help message ---
2227
2228                 STMFD   R13!,{R0-R4,R14}        ;Stack registers
2229                 LDR     R14,[R1,#16]            ;Get the message number
2230                 LDR     R2,=&502                ;Load the constant number
2231                 CMP     R14,R2                  ;Is it a help message
2232                 LDMNEFD R13!,{R0-R3,R14}        ;No -- load registers
2233                 BICNES  PC,R14,#C_flag          ;...couldn't understand
2234
2235                 ; --- Find the item that we are over ---
2236
2237                 ADD     R4,R1,#20               ;Point to the coordinates
2238                 SUB     R13,R13,#36             ;Get a small block
2239                 MOV     R1,R13                  ;Point to the block
2240                 LDR     R2,[R10,#hHandle]       ;Get the window handle
2241                 STR     R2,[R1,#0]              ;Store the window handle
2242                 SWI     Wimp_GetWindowState     ;Get the window state
2243                 LDR     R0,[R4,#0]              ;Get the mouse x coord
2244                 LDR     R2,[R13,#20]            ;Get the scroll x position
2245                 LDR     R3,[R13,#4]             ;Get the x0 position
2246                 ADD     R0,R0,R2                ;Calculate workarea relative
2247                 SUB     R0,R0,R3                ;...x position
2248                 LDR     R1,[R4,#4]              ;Get the mouse y coord
2249                 LDR     R2,[R13,#24]            ;Get the scroll y position
2250                 LDR     R3,[R13,#16]            ;Get the y1 position
2251                 ADD     R1,R1,R2                ;Calculate workarea relative
2252                 SUB     R1,R1,R3                ;...y position
2253                 ADD     R13,R13,#36             ;Get the block back
2254                 STMFD   R13!,{R0,R1}            ;Stack the coordinates
2255                 BL      tms__findItem           ;Find the associated icon
2256
2257                 CMP     R8,#0                   ;Were we over an item?
2258                 BEQ     %05tms__eventHandler    ;No -- try the tearoff bar
2259
2260                 ; --- Send the help event to the users handler ---
2261
2262                 STMFD   R13!,{R10,R12}          ;Save these registers
2263                 MOV     R0,#mEvent_help         ;Help on item required
2264                 LDR     R1,tms__itemIndex       ;The items index
2265                 LDR     R2,tms__itemOver        ;Point to packed item def.
2266                 ADD     R3,R8,#iHandler         ;Point to the handler
2267                 LDMIA   R3,{R3,R10,R12}         ;Load the values
2268                 TEQ     R3,#0                   ;Sanity check
2269                 MOV     R14,PC                  ;Set up the return address
2270                 MOVNE   PC,R3                   ;Call the handler
2271                 LDMFD   R13!,{R10,R12}          ;Get my registers back
2272                 ADD     R13,R13,#8              ;Skip over the coordinates
2273                 B       %09tms__eventHandler    ;And return
2274
2275                 ; --- Was the click on the tearoff bar? ---
2276
2277 05              LDR     R0,tms__flags           ;Get the flags word
2278                 LDMFD   R13!,{R0,R1}            ;Get the coordiantes
2279                 LDR     R2,[R10,#hFlags]        ;Get the menu flags
2280                 TST     R2,#hFlag__tearable     ;Is there a bar?
2281                 BEQ     %09tms__eventHandler    ;No -- branch ahead
2282                 CMP     R1,#-tms__barHeight     ;Did we click in the bar?
2283                 BLT     %09tms__eventHandler    ;No -- branch ahead
2284                 CMP     R1,#-4                  ;The top of the icon
2285                 BGT     %09tms__eventHandler    ;Not in icon -- return
2286                 CMP     R1,#-(tms__barHeight-4) ;The bottom level
2287                 BLT     %09tms__eventHandler    ;Not in icon -- return
2288                 TST     R2,#hFlag__torn         ;Has the menu been torn off
2289                 BNE     %06tms__eventHandler    ;Yes -- deal with that
2290
2291                 ; --- Was the click in the tear icon? ---
2292
2293                 CMP     R0,#4                   ;The left hand side
2294                 BLT     %09tms__eventHandler    ;Not in icon -- return
2295                 CMP     R0,#68                  ;The right hand side
2296                 BGT     %09tms__eventHandler    ;Not in icon -- return
2297                 ADRL    R0,tms__helpTear        ;Point to the tear message
2298                 BL      msgs_lookup             ;Look it up in messages file
2299                 BL      help_add                ;And send it to help
2300                 B       %09tms__eventHandler    ;Return to caller
2301
2302                 ; --- The menu is torn off -- what did we click in? ---
2303
2304 06              CMP     R0,#4                   ;The left hand side
2305                 BLT     %09tms__eventHandler    ;Not in icon -- return
2306                 CMP     R0,#70                  ;The right hand side
2307                 ADRLEL  R0,tms__helpClose       ;Point to the close message
2308                 BLLE    msgs_lookup             ;Look it up in messages file
2309                 BLLE    help_add                ;And send it to help
2310                 BLE     %09tms__eventHandler    ;Return to caller
2311
2312                 ; --- Was it in the fold icon ---
2313
2314 07              LDR     R2,[R10,#hTotWidth]     ;The total menu width
2315                 SUB     R2,R2,#60               ;LHS of tear icon
2316                 CMP     R0,R2                   ;Where did we click?
2317                 BLT     %09tms__eventHandler    ;Not in it, that's for sure
2318                 ADD     R2,R2,#56               ;RHS of tear icon
2319                 CMP     R0,R2                   ;Where did we click?
2320                 ADRLEL  R0,tms__helpFold        ;Point to the fold message
2321                 BLLE    msgs_lookup             ;Look it up in messages file
2322                 BLLE    help_add                ;And send it to help
2323
2324 09              LDMFD   R13!,{R0-R4,R14}        ;Load back registers
2325                 ORRS    PC,R14,#C_flag          ;Return with carry set
2326
2327                 ; --- OpenWindow request ---
2328
2329 10              STMFD   R13!,{R14}              ;Stack some registers
2330                 BL      screen_justChangedMode  ;Has there been a mode change
2331                 SWICC   Wimp_OpenWindow         ;No -- open the window
2332                 LDMCCFD R13!,{PC}^              ;...and return to caller
2333                 STMFD   R13!,{R0-R3}            ;Stack some more registers
2334                 BL      tms__ensureWindowOK     ;Ensure window is OK
2335                 SUB     R13,R13,#20             ;Get me a block
2336                 MOV     R1,R13                  ;Point to it
2337                 SWI     Wimp_GetPointerInfo     ;Get the pointer information
2338                 LDR     R0,[R1,#12]             ;Get the window ptr is over
2339                 LDR     R1,[R10,#hHandle]       ;And window handle of menu
2340                 CMP     R0,R1                   ;Are they the same?
2341                 BNE     %15tms__eventHandler    ;No -- return
2342                 LDR     R0,tms__oldHandle       ;Get the idle handler handle
2343                 CMP     R0,#0                   ;Is there one?
2344                 BNE     %15tms__eventHandler    ;Yes -- return
2345                 MOV     R0,#0                   ;Frequency -- quick please
2346                 ADRL    R1,tms__idleHandler     ;Point to the handler
2347                 MOV     R2,R10                  ;Pass menu in R10
2348                 MOV     R3,R12                  ;And workspace in R12
2349                 BL      idle_handler            ;Add in the handler
2350                 STR     R10,tms__oldHandle      ;And store away new handle
2351
2352 15              ADD     R13,R13,#20             ;Get the stack back
2353                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
2354
2355                 ; --- CloseWindow request ---
2356
2357 20              SWI     Wimp_CloseWindow        ;Close the window
2358                 MOVS    PC,R14                  ;And return
2359
2360                 ; --- Pointer leaving ---
2361
2362 30              STMFD   R13!,{R0,R2,R10,R14}    ;Stack some registers
2363                 LDR     R0,tms__oldHandle       ;Is there an idle handle hnd
2364                 CMP     R0,#0                   ;Is there one?
2365                 LDMEQFD R13!,{R0,R2,R10,PC}^    ;No -- return
2366                 BL      tms__cleanUp            ;Yes -- clean up a bit
2367                 MOV     R10,R0                  ;Point to the menu
2368                 LDR     R2,[R10,#hFlags]        ;Get the flags for the menu
2369                 TST     R2,#hFlag__warned       ;Have we be warned?
2370                 LDMNEFD R13!,{R0,R2,R10,PC}^    ;Yes -- return
2371                 LDR     R2,[R0,#hSelected]      ;Point to the selected item
2372                 CMP     R2,#0                   ;Is there one?
2373                 BLNE    tms__unHighlight        ;Un-highlight the item
2374                 LDMFD   R13!,{R0,R2,R10,PC}^    ;And return to caller
2375
2376                 ; --- Pointer entering ---
2377
2378 40              STMFD   R13!,{R0-R3,R14}        ;Stack some registers
2379                 LDR     R0,tms__oldHandle       ;Is there an idle handle hnd
2380                 CMP     R0,#0                   ;Is there one?
2381                 BLNE    tms__cleanUp            ;Yes -- clean up a bit
2382                 MOV     R0,#0                   ;Frequency -- quick please
2383                 ADRL    R1,tms__idleHandler     ;Point to the handler
2384                 MOV     R2,R10                  ;Pass menu in R10
2385                 MOV     R3,R12                  ;And workspace in R12
2386                 BL      idle_handler            ;Add in the handler
2387                 STR     R2,tms__oldHandle       ;We have an idle handler
2388                 BL      tms__alarm2             ;Allow item selection
2389                 LDMFD   R13!,{R0-R3,PC}^        ;And return to caller
2390
2391 tms__helpTear   DCB     "TMST",0
2392 tms__helpClose  DCB     "TMSC",0
2393 tms__helpFold   DCB     "TMSF",0
2394
2395                 LTORG
2396
2397 ; --- tms_help ---
2398 ;
2399 ; On entry:     R0 == pointer to base message tag
2400 ;               R1 == index of menu item
2401 ;
2402 ; On exit:      --
2403 ;
2404 ; Use:          Adds a string to the help message found by adding the menu
2405 ;               item number to the base message tag.
2406
2407                 EXPORT  tms_help
2408 tms_help        ROUT
2409
2410                 CMP     R1,#0                   ;Is the menu item sane?
2411                 MOVLTS  PC,R14                  ;No -- don't trust Tim
2412                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
2413                 MOV     R1,R0                   ;Point to base message tag
2414                 MOV     R0,R11                  ;Point to scratchpad
2415                 BL      str_cpy                 ;Add the string in there
2416                 MOV     R1,R0                   ;Point to terminating null
2417                 MOV     R2,#25                  ;Should be 25 bytes left over
2418                 LDR     R0,[R13,#4]             ;Get his item number
2419                 SWI     OS_ConvertInteger4      ;Tack it on the end
2420                 MOV     R0,R11                  ;Point to the message tag
2421                 BL      msgs_lookup             ;Translate it nicely
2422                 BL      help_add                ;Add it to the help string
2423                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
2424
2425                 LTORG
2426
2427 ;----- Workspace ------------------------------------------------------------
2428
2429                 AREA    |Sapphire$$LibData|,CODE,READONLY
2430
2431                 DCD     tms__wSize              ;Workspace size
2432                 DCD     tms__wSpace             ;Workspace pointer
2433                 DCD     0                       ;Scratchpad size
2434                 DCD     tms_init                ;Initialisation
2435
2436 ;----- That's all, folks ----------------------------------------------------
2437
2438                 END