Home » Archimedes archive » Micro User » MU 1991-07.adf » PD-Stuff » Utilities/!PlaceIt/!PlaceIt
Utilities/!PlaceIt/!PlaceIt
This website contains an archive of files for the Acorn Electron, BBC Micro, Acorn Archimedes, Commodore 16 and Commodore 64 computers, which Dominic Ford has rescued from his private collection of floppy disks and cassettes.
Some of these files were originally commercial releases in the 1980s and 1990s, but they are now widely available online. I assume that copyright over them is no longer being asserted. If you own the copyright and would like files to be removed, please contact me.
| Tape/disk: | Home » Archimedes archive » Micro User » MU 1991-07.adf » PD-Stuff |
| Filename: | Utilities/!PlaceIt/!PlaceIt |
| Read OK: | ✔ |
| File size: | 11565 bytes |
| Load address: | 0000 |
| Exec address: | 0000 |
File contents
10REM > !PlaceIt
20REM by Ian Ashley (pmf@uk.ac.warwick.cs) on 6/10/90
30REM Update to 1.03 on 19/1/91
40
50space%=&2000 : REM 8K
60
70v_flag=1 << 28
80
90stacklen% = 32
100
110REM format of each data entry in the linked list (stored as a heap)
120
130next = 0
140size = 4
150offset_to_leafname = 8
160icon_handle = 12
170selected = 13
180x_position = 16
190y_position = 20
200sprite_name = 24
210filetype = 40
220filename = 44
230
240REM needed to stop errors on first pass
250
260background_window_handle = &9000
270mode_changed = &9000
280number_selected = &9400
290start_linked_list = &9800
300heap_start = start_linked_list
310
320DIM code% space%
330
340FOR opt%=12 TO 14 STEP 2
350P%=&8000
360O%=code%
370L%=code%+space% : REM Upper limit for assembly
380[
390 opt opt%
400 adr r13,stack
410 ldr r1,task
420 mov r0,#200 ; last known wimp 2.00
430 adr r2,switcher_name ; r2 -> "Place It"
440 swi "XWimp_Initialise"
450 bvs startup_error
460 str r1,task_handle
470 bvs startup_error
480 bl define_background_window
490 bvs startup_error
500 bl define_info_window
510 bvs startup_error
520 bl set_initial_conditions
530 bvs startup_error
540 bl load_config_file
550 bvs startup_error
560 b poll
570
580.switcher_name
590 equs "Place It"
600 equb 0
610 align
620.task_handle
630 equd 0
640.task
650 equs "TASK"
660
670; -----------------------------------------------------------------------------
680; report an error using Wimp_ReportError, set could not start up flag then
690; closedown
700; entry
710; r0 -> error block
720; exit
730; doesn't
740
750.startup_error
760 adr r1,poll_space
770 ldr r2,[r0],#4
780 str r2,[r1],#4
790 adr r2,startup_error_message
800.startup_error_loop1
810 ldrb r3,[r2],#1
820 cmp r3,#0
830 strneb r3,[r1],#1
840 bne startup_error_loop1
850.startup_error_loop2
860 ldrb r3,[r0],#1
870 cmp r3,#0
880 strneb r3,[r1],#1
890 bne startup_error_loop2
900.startup_error_loop3
910 ldrb r3,[r2],#1
920 strb r3,[r1],#1
930 cmp r3,#0
940 bne startup_error_loop3
950 adr r0,poll_space
960 mov r1,#2 ; cancel only
970 bl report_error
980 bl closedown
990 swi "OS_Exit"
1000.startup_error_message
1010 equs "PlaceIt could not startup ("+CHR$0
1020 equs ") and must exit immediately"+CHR$0
1030 align
1040
1050; -----------------------------------------------------------------------------
1060; poll space, workspace and stack
1070
1080.poll_space
1090 equs STRING$(128,CHR$0)
1100 equs STRING$(128,CHR$0)
1110.workspace
1120 equs STRING$(60,CHR$0)
1130.stack_start
1140 equs STRING$(stacklen%,CHR$0)
1150.stack
1160
1170; -----------------------------------------------------------------------------
1180; wimp poll loop
1190
1200.poll
1210 mov r0,#%110001 ; Mask
1220 adr r1,poll_space
1230 swi "XWimp_Poll"
1240 bvs fatal_error
1250 teq r0,#1
1260 beq redraw_window
1270 teq r0,#2
1280 beq open_window
1290 teq r0,#3
1300 beq close_window
1310 teq r0,#6
1320 beq mouse_button
1330 teq r0,#7
1340 beq drag_end
1350 teq r0,#9
1360 beq menu_select
1370 teq r0,#17
1380 teqne r0,#18
1390 beq message
1400 teq r0,#19
1410 beq message_acknowledged
1420 b poll
1430
1440; -----------------------------------------------------------------------------
1450; redraw window request has been sent
1460
1470.redraw_window
1480 swi "XWimp_RedrawWindow"
1490 bvs fatal_error
1500 b poll
1510
1520; -----------------------------------------------------------------------------
1530; open window request has been sent
1540
1550.open_window
1560 adr r2,mode_changed-&1000
1570 add r2,r2,#&1000
1580 ldrb r0,[r2]
1590 teq r0,#1 ; see if mode has just changed
1600 adreq r1,background_window_handle-&1000
1610 addeq r1,r1,#&1000
1620 moveq r0,#0
1630 streqb r0,[r2]
1640 swi "XWimp_OpenWindow"
1650 bvs fatal_error
1660 b poll
1670
1680; -----------------------------------------------------------------------------
1690; close window request has been sent
1700
1710.close_window
1720 swi "XWimp_CloseWindow"
1730 bvs fatal_error
1740 b poll
1750
1760; -----------------------------------------------------------------------------
1770; mouse click request has been sent
1780
1790.mouse_button
1800 ldr r0,[r1,#12] ; r0=window handle of click
1810 adr r2,background_window_handle-&1000
1820 add r2,r2,#&1000
1830 ldr r2,[r2]
1840 cmp r0,r2 ; is it on our window ?
1850 bne poll ; poll if not
1860 ldr r0,[r1,#8] ; r0=button state
1870 tst r0,#2 ; see if middle button clicked
1880 bne open_menu ; if so open menu
1890 ldr r2,[r1,#16] ; r2=icon handle clicked on
1900 cmn r2,#1 ; see if not on icon
1910 moveq r0,r0,lsl #8 ; if shift button state to right pos
1920 tst r0,#%101 ; see if button doubled clicked
1930 bne double_clicked
1940 tst r0,#%101 * 16 ; see if drag started
1950 bne drag_started
1960 tst r0,#%001 * 256 ; see if adjust clicked
1970 bne adjust_clicked
1980.select_clicked
1990 cmn r2,#1 ; see if on workarea
2000 bleq unselect_all ; if so unselect all
2010 beq poll ; then poll
2020 bl find_icon
2030 ldrb r3,[r4,#selected]
2040 teq r3,#1 ; see if selected
2050 beq poll ; if so poll
2060 bl unselect_all
2070 bl select_icon ; select icon
2080 mov r2,#1
2090 adr r3,number_selected-&1000
2100 add r3,r3,#&1000
2110 strb r2,[r3]
2120 strb r2,[r4,#selected]
2130 b poll
2140.adjust_clicked
2150 cmn r2,#1 ; see if on workarea
2160 beq poll ; if so poll
2170 bl find_icon
2180 ldrb r3,[r4,#selected]
2190 teq r3,#1 ; see if icon unselected
2200 ; or selected by menu
2210 blne select_icon
2220 bleq unselect_icon
2230 movne r3,#1
2240 moveq r3,#0
2250 strb r3,[r4,#selected]
2260 adr r4,number_selected-&1000
2270 add r4,r4,#&1000
2280 ldrb r3,[r4]
2290 addne r3,r3,#1
2300 subeq r3,r3,#1
2310 strb r3,[r4]
2320 b poll
2330.drag_started
2340 teq r0,#1 * 16 ; see if adjust used in drag
2350 moveq r0,#&ff
2360 movne r0,#0
2370 strb r0,delete_after_drag
2380 ldmia r1,{r0,r2}
2390 str r0,drag_x_start
2400 str r2,drag_y_start
2410 mov r0,#129 ; scan keyboard
2420 mov r1,#&ff ; scan for both shifts
2430 mov r2,r1
2440 swi "XOS_Byte"
2450 bvs fatal_error
2460 teq r2,#&ff ; see if either shift pressed
2470 streqb r2,delete_after_drag ; if so store so as know to delete
2480 ; icon when drag has finished
2490 adr r1,poll_space
2500 ldr r2,[r1,#16]
2510 bl find_icon
2520 ldrb r0,[r4,#selected]
2530 teq r0,#1 ; see if already selected
2540 movne r0,#1
2550 strneb r0,[r4,#selected]
2560 ldrneb r0,number_selected
2570 addne r0,r0,#1
2580 strneb r0,number_selected
2590 blne select_icon
2600 adr r1,workspace
2610 mov r0,#5 ; drag fixed size rotating box
2620 str r0,[r1,#4]
2630 ldr r2,screen_maxx ; r2 will be min x of selected icons
2640 ldr r3,screen_maxy ; r3 will be min y of selected icons
2650 mov r4,#0 ; r4 will be max x of selected icons
2660 mov r5,r4 ; r5 will be min y of selected icons
2670 adr r6,start_linked_list-&1400
2680 add r6,r6,#&1400
2690 ldr r6,[r6]
2700.drag_started_loop
2710 ldrb r0,[r6,#selected]
2720 teq r0,#0
2730 beq drag_started_loop_skip
2740 ldr r0,[r6,#x_position]
2750 cmp r0,r2
2760 movlt r2,r0
2770 cmp r0,r4
2780 movgt r4,r0
2790 ldr r0,[r6,#y_position]
2800 cmp r0,r3
2810 movlt r3,r0
2820 cmp r0,r5
2830 movgt r5,r0
2840.drag_started_loop_skip
2850 ldr r6,[r6,#next]
2860 teq r6,#0
2870 bne drag_started_loop
2880 sub r2,r2,#8
2890 str r2,[r1,#8]
2900 sub r3,r3,#4
2910 str r3,[r1,#12]
2920 add r4,r4,#160+10
2930 str r4,[r1,#16]
2940 add r5,r5,#108+4
2950 str r5,[r1,#20]
2960
2970 adr r6,drag_x_min
2980 stmia r6,{r2-r5} ; store for later use
2990
3000 ldr r6,drag_x_start
3010 ldr r7,drag_y_start
3020
3030 ldr r0,screen_maxx
3040 sub r0,r0,r6
3050 add r0,r0,r4
3060 str r0,[r1,#32] ; max x of parent box
3070
3080 ldr r0,screen_maxy
3090 sub r0,r0,r7
3100 add r0,r0,r5
3110 str r0,[r1,#36] ; max y of parent box
3120
3130 sub r0,r2,r6
3140 str r0,[r1,#24] ; min x of parent box
3150
3160 sub r0,r3,r7
3170 str r0,[r1,#28] ; min y of parent box
3180
3190 swi "XWimp_DragBox"
3200 bvs fatal_error
3210 b poll
3220.drag_x_start
3230 equd 0
3240.drag_y_start
3250 equd 0
3260.drag_x_min
3270 equd 0
3280.drag_y_min
3290 equd 0
3300.drag_x_max
3310 equd 0
3320.drag_y_max
3330 equd 0
3340.double_clicked
3350 str r0,button_state
3360 mov r3,r2
3370 mov r0,#129 ; scan keyboard
3380 mov r1,#&ff ; scan for both shifts
3390 mov r2,r1
3400 swi "XOS_Byte"
3410 bvs fatal_error
3420 mov r5,r2
3430 mov r2,r3
3440 bl find_icon
3450 ldrb r3,[r4,#selected]
3460 teq r3,#1 ; see if selected
3470 bleq unselect_icon
3480 ldreqb r3,number_selected
3490 subeq r3,r3,#1
3500 streqb r3,number_selected
3510 adr r1,poll_space+&400
3520 sub r1,r1,#&400
3530 mov r0,#5 ; dataopen message
3540 str r0,[r1,#16]
3550 ldr r0,background_window_handle
3560 str r0,[r1,#20]
3570 ldr r0,[r4,#x_position]
3580 str r0,[r1,#28]
3590 ldr r0,[r4,#y_position]
3600 str r0,[r1,#32]
3610 mov r0,#0 ; we are originating the message
3620 str r0,[r1,#12]
3630 str r0,[r1,#36]
3640 ldr r0,[r4,#filetype]
3650 teq r5,#&ff ; see if either shift was pressed
3660 bne no_shift
3670 cmp r0,#&2000 ; see if application
3680 subeq r0,r0,#&1000 ; if so set it to directory
3690.no_shift
3700 str r0,[r1,#40]
3710 add r0,r4,#filename
3720 add r2,r1,#44
3730.double_clicked_loop
3740 ldrb r3,[r0],#1
3750 strb r3,[r2],#1
3760 teq r3,#0
3770 bne double_clicked_loop
3780 sub r2,r2,r1 ; r2 = length of message
3790 add r2,r2,#3
3800 bic r2,r2,#3 ; word align
3810 str r2,[r1]
3820 mov r0,#18 ; reply needed
3830 mov r2,#0 ; broadcast message
3840 swi "XWimp_SendMessage"
3850 bvs fatal_error
3860 ldr r0,[r1,#8]
3870 ldr r2,button_state ; must load this first as stored
3880 ; at same address as message_myref
3890 str r0,message_myref
3900 tst r2,#1 ; see if adjust double clicked
3910 blne remove_icon
3920 mov r0,#42
3930 strb r0,delete_after_drag ; tell us no drag occured
3940 b poll
3950
3960; -----------------------------------------------------------------------------
3970; remove icon from screen and linked list
3980; entry
3990; r4 -> linked list entry
4000
4010.remove_icon
4020 stmfd r13!,{r0-r4,r14}
4030 adr r1,start_linked_list-&1000
4040 add r1,r1,#&1000
4050.remove_icon_loop
4060 ldr r2,[r1,#next]
4070 teq r2,r4 ; see if found linked list entry before
4080 ; the one we are deleting
4090 movne r1,r2
4100 bne remove_icon_loop
4110 ldr r2,[r4,#next] ; remove the entry from the
4120 str r2,[r1,#next] ; linked list
4130 bl delete_icon
4140 bl free_heap_block
4150 ldrb r2,number_of_icons
4160 sub r2,r2,#1
4170 strb r2,number_of_icons
4180 ldmfd r13!,{r0-r4,pc}
4190
4200; -----------------------------------------------------------------------------
4210; delete an icon and update screen
4220; entry
4230; r4 -> linked list entry
4240
4250.delete_icon
4260 stmfd r13!,{r0-r4}
4270 adr r1,delete_space
4280 ldr r0,background_window_handle
4290 str r0,[r1]
4300 ldrb r0,[r4,#icon_handle]
4310 str r0,[r1,#4]
4320 swi "XWimp_DeleteIcon"
4330 bvs fatal_error
4340 ldr r0,background_window_handle
4350 ldr r1,[r4,#x_position]
4360 ldr r2,[r4,#y_position]
4370 add r3,r1,#10*16
4380 add r4,r2,#108
4390 swi "XWimp_ForceRedraw"
4400 bvs fatal_error
4410 ldmfd r13!,{r0-r4}
4420 movs pc,r14
4430.delete_space
4440 equd 0
4450 equd 0
4460
4470; -----------------------------------------------------------------------------
4480; open the menu
4490
4500.open_menu
4510 ldrb r2,number_selected
4520 teq r2,#0 ; see if no icon selected
4530 teqne r2,#&ff ; or icon selected by menu
4540 bne icons_selected
4550 teq r2,#&ff
4560 bleq unselect_menu_selected_icon
4570 ldr r2,[r1,#16] ; icon clicked on
4580 cmn r2,#1 ; see if on icon
4590 beq icons_selected ; skip if not
4600 bl find_icon
4610 mov r3,#2
4620 strb r3,[r4,#selected] ; mark as selected by menu
4630 ldrb r2,[r4,#icon_handle]
4640 bl select_icon
4650 mvn r3,#0
4660 strb r3,number_selected
4670.icons_selected
4680 ldrb r2,number_of_icons
4690 teq r2,#0 ; see if no icons on backdrop
4700 ldr r3,select_all_flags
4710 orreq r3,r3,#1 << 22 ; set shaded bit if no icons
4720 bicne r3,r3,#1 << 22 ; unset shaded bit otherwise
4730 str r3,select_all_flags
4740
4750 ldrb r2,number_selected
4760 teq r2,#0 ; see if no icons selected
4770 ldr r3,clear_selection_flags
4780 orreq r3,r3,#1 << 22 ; set shaded bit if no icons selected
4790 bicne r3,r3,#1 << 22 ; unset shaded bit otherwise
4800 str r3,clear_selection_flags
4810
4820 ldr r3,remove_flags
4830 orreq r3,r3,#1 << 22 ; set shaded bit if no icons
4840 bicne r3,r3,#1 << 22 ; unset shaded bit otherwise
4850 str r3,remove_flags
4860
4870 ldr r2,[r1] ; r2 = mouse x coordinate
4880 sub r2,r2,#144 ; x coordinate to open menu at
4890 ldr r3,[r1,#4] ; r3 = mouse y coordinate
4900 add r3,r3,#16 ; y coordinate to open menu at
4910 adr r1,main_menu
4920 swi "XWimp_CreateMenu"
4930 bvs fatal_error
4940 b poll
4950
4960; -----------------------------------------------------------------------------
4970; menu data blocks
4980
4990.main_menu
5000 FNstring("Place It")
5010 equb 7
5020 equb 2
5030 equb 7
5040 equb 0
5050 equd 256
5060 equd 44
5070 equd 0
5080
5090 equd 0
5100.info_window_handle
5110 equd -1
5120 equd 1+(1 << 5)+(7 << 24)
5130 FNstring("Info")
5140
5150 equd 0
5160 equd display_menu
5170 equd 1+(1 << 5)+(7 << 24)
5180 FNstring("Display")
5190
5200 equd 0
5210 equd -1
5220.remove_flags
5230 equd 1+(1 << 5)+(7 << 24)
5240 FNstring("Remove")
5250
5260 equd 0
5270 equd -1
5280.select_all_flags
5290 equd 1+(1 << 5)+(7 << 24)
5300 FNstring("Select all")
5310
5320 equd 0
5330 equd -1
5340.clear_selection_flags
5350 equd 1+(1 << 5)+(1 << 8)+(7 << 24)
5360 equd clear_selection_indirected
5370 equd -1
5380 equd 16
5390
5400 equd 0
5410 equd -1
5420 equd 1+(1 << 5)+(1 << 8)+(7 << 24)
5430 equd save_backdrop_indirected
5440 equd -1
5450 equd 14
5460
5470 equd &80 ; last menu item
5480 equd -1
5490 equd 1+(1 << 5)+(7 << 24)
5500 FNstring("Quit")
5510.end_main_menu
5520
5530.display_menu
5540 FNstring("Display")
5550 equb 7
5560 equb 2
5570 equb 7
5580 equb 0
5590 equd 176
5600 equd 44
5610 equd 0
5620
5630.black_text_tick
5640 equd 1
5650 equd -1
5660 equd 1+(1 << 5)+(7 << 24)
5670 FNstring("Black text")
5680
5690.white_text_tick
5700 equd &80 ; last menu item
5710 equd -1
5720 equd 1+(1 << 5)+(7 << 24)
5730 FNstring("White text")
5740
5750.clear_selection_indirected
5760 equs "Clear selection"+CHR$0
5770.save_backdrop_indirected
5780 equs "Save backdrop"+CHR$0
5790 align
5800
5810; -----------------------------------------------------------------------------
5820; Our drag operation has ended
5830
5840.drag_end
5850 adr r1,workspace+&400
5860 sub r1,r1,#&400
5870 swi "XWimp_GetPointerInfo"
5880 bvs fatal_error
5890 ldr r0,[r1,#12]
5900 ldr r3,background_window_handle
5910 teq r0,r3 ; see if dragged onto our window
5920 bne get_task_name
5930 ldmia r1,{r0,r2} ; get coords where drag ended
5940 str r3,[r1] ; store window handle at r1
5950 ldr r3,drag_x_start
5960 ldr r4,drag_y_start
5970 sub r3,r0,r3
5980 sub r4,r2,r4
5990 adr r5,start_linked_list-&1000
6000 add r5,r5,#&1000
6010 ldr r5,[r5]
6020.drag_end_loop
6030 ldrb r0,[r5,#selected]
6040 teq r0,#0
6050 beq drag_end_loop_skip
6060 ldrb r0,[r5,#icon_handle]
6070 str r0,[r1,#4]
6080 swi "XWimp_DeleteIcon"
6090 bvs fatal_error
6100 ldr r0,[r5,#x_position]
6110 add r0,r0,r3
6120 str r0,[r5,#x_position]
6130 str r0,[r1,#4]
6140 add r0,r0,#10*16
6150 str r0,[r1,#12]
6160 ldr r0,[r5,#y_position]
6170 add r0,r0,r4
6180 str r0,[r5,#y_position]
6190 str r0,[r1,#8]
6200 add r0,r0,#108
6210 str r0,[r1,#16]
6220 ldr r0,icon_flags
6230 str r0,[r1,#20]
6240 ldr r0,[r5,#offset_to_leafname]
6250 add r0,r0,r5
6260 str r0,[r1,#24]
6270 add r0,r5,#sprite_name
6280 str r0,[r1,#28]
6290 mov r0,#12
6300 str r0,[r1,#32]
6310 swi "XWimp_CreateIcon"
6320 bvs fatal_error
6330 strb r0,[r5,#icon_handle]
6340.drag_end_loop_skip
6350 ldr r5,[r5,#next]
6360 teq r5,#0
6370 bne drag_end_loop
6380 adr r0,drag_x_min ; get initial coordinates of
6390 ldmia r0,{r1-r4} ; box dragged
6400 ldr r0,background_window_handle
6410 swi "XWimp_ForceRedraw"
6420 bvs fatal_error
6430 bl unselect_all
6440 b poll
6450.get_task_name
6460 adr r1,poll_space+&800
6470 sub r1,r1,#&800
6480 swi "XWimp_GetPointerInfo"
6490 bvs fatal_error
6500 ldr r2,[r1,#12]
6510 str r2,datasave_window_handle ; store window handle
6520 ldr r3,[r1,#16]
6530 str r3,datasave_icon_handle ; store icon handle
6540 ldr r0,[r1,#0]
6550 str r0,datasave_mouse_x ; store mouse x
6560 ldr r0,[r1,#4]
6570 str r0,datasave_mouse_y ; store mouse y
6580
6590 adr r1,workspace+&400
6600 mov r0,#24 ; length of message block
6610 str r0,[r1,#-&400]!
6620 mov r0,#0
6630 str r0,[r1,#12] ; original message
6640 mov r0,#&40000
6650 add r0,r0,#&c6 ; message_tasknamerq
6660 str r0,[r1,#16]
6670 mov r0,#19 ; use to find task handle of window
6680 ; r2,3 already set
6690 swi "XWimp_SendMessage" ; no message will be sent but r2 = task
6700 bvs fatal_error ; handle of window
6710 str r2,[r1,#20]
6720 mov r0,#17 ; no reply wanted
6730 mov r2,#0 ; broadcast message
6740 swi "XWimp_SendMessage"
6750 bvs fatal_error
6760 ldr r0,[r1,#8]
6770 str r0,message_myref
6780 b poll
6790
6800.tasknameis
6810 ldr r0,start_filer_name
6820 ldr r2,[r1,#28]
6830 teq r0,r2 ; see if the same
6840 bne send_dataload_message
6850 ldrb r0,[r1,#32]
6860 teq r0,#ASC"r"
6870 bne send_dataload_message
6880 ldrb r0,[r1,#33]
6890 teq r0,#0
6900 bne send_dataload_message
6910 mov r0,#1
6920 strb r0,save_to_filer ; set flag (message type)
6930 b send_datasaveload_message
6940.start_filer_name
6950 equs "File"
6960.send_dataload_message
6970 mov r0,#3
6980 strb r0,save_to_filer ; set flag (message type)
6990.send_datasaveload_message
7000 adr r4,start_linked_list-&1000
7010 add r4,r4,#&1000
7020 ldr r4,[r4]
7030.send_datasaveload_message_loop
7040 adr r1,poll_space+&800
7050 sub r1,r1,#&800
7060 ldrb r0,[r4,#selected]
7070 teq r0,#0 ; see if selected
7080 beq send_datasaveload_message_not_selected
7090 bl unselect_icon
7100 ldrb r0,number_selected
7110 sub r0,r0,#1
7120 strb r0,number_selected
7130 ldr r0,[r4,#filetype]
7140 str r0,[r1,#40]
7150 mov r0,#17 ; read catalogue info, no path
7160 add r1,r4,#filename
7170 mov r6,r4 ; preserve r4
7180 swi "XOS_File"
7190 movvs r4,r6 ; restore r4
7200 adrvs r14,send_datasaveload_message_not_selected
7210 bvs report_error_ok
7220 teq r0,#0
7230 bne send_datasaveload_message_skip
7240 mov r4,r6 ; restore r4
7250 mov r0,#19 ; generate error
7260 swi "XOS_File"
7270 bl report_error_ok
7280 b send_datasaveload_message_not_selected
7290.send_datasaveload_message_skip
7300 adr r1,poll_space+&800
7310 sub r1,r1,#&800 ; reset r1
7320 str r4,[r1,#36] ; store length of file
7330 mov r4,r6 ; restore r4
7340 ldrb r5,save_to_filer
7350 teq r5,#1 ; see if saving to filer
7360 ldreq r2,[r4,#offset_to_leafname]
7370 addeq r2,r2,r4 ; if so use leafname
7380 addne r2,r4,#filename ; not so use full name
7390 add r3,r1,#44
7400.send_datasaveload_message_loop2
7410 ldrb r5,[r2],#1
7420 strb r5,[r3],#1
7430 teq r5,#0
7440 bne send_datasaveload_message_loop2
7450 sub r3,r3,r1 ; r3 = message length
7460 add r3,r3,#3
7470 bic r3,r3,#3 ; round up to word boundary
7480 str r3,[r1]
7490 mov r0,#0 ; we are originating the message
7500 str r0,[r1,#12]
7510 ldrb r0,save_to_filer
7520 str r0,[r1,#16] ; set message type
7530 ldr r0,datasave_mouse_x
7540 str r0,[r1,#28]
7550 ldr r0,datasave_mouse_y
7560 str r0,[r1,#32]
7570 mov r0,#18 ; reply needed
7580 ldr r2,datasave_window_handle ; r2 = destination window handle
7590 str r2,[r1,#20]
7600 ldr r3,datasave_icon_handle ; r3 = destination window handle
7610 ; incase on iconbar
7620 str r3,[r1,#24]
7630 swi "XWimp_SendMessage"
7640 bvs fatal_error
7650 ldr r0,[r1,#8]
7660 str r0,message_myref
7670 str r4,datasave_where_up_to
7680 b poll ; poll to receive message reply
7690.send_datasaveload_message_continue
7700 ldr r4,datasave_where_up_to
7710.send_datasaveload_message_not_selected
7720 adr r1,poll_space+&800
7730 sub r1,r1,#&800
7740 ldr r4,[r4]
7750.send_datasaveload_message_continue2
7760 teq r4,#0
7770 bne send_datasaveload_message_loop
7780 b poll
7790
7800.datasave_where_up_to
7810 equd 0
7820.datasave_window_handle
7830 equd 0
7840.datasave_icon_handle
7850 equd 0
7860.datasave_mouse_x
7870 equd 0
7880.datasave_mouse_y
7890 equd 0
7900
7910; -----------------------------------------------------------------------------
7920; The user has clicked on our meny
7930
7940.menu_select
7950 adr r1,pointer_info
7960 swi "XWimp_GetPointerInfo"
7970 bvs fatal_error
7980 adr r1,poll_space+&800
7990 sub r1,r1,#&800
8000 ldr r0,[r1] ; r0 = first menu entry
8010 cmn r0,#1 ; see if on menu entry
8020 addne pc,pc,r0,lsl #2 ; was so dispatch to correct routine
8030 b poll ; not on menu entry so poll
8040.jump_table
8050 b poll ; info
8060 b menu_display ; display submenu
8070 b remove ; remove
8080 b select_all ; select_all
8090 b clear_selection ; clear_selection
8100 b save_backdrop ; save_backdrop
8110 b closedown_and_exit ; quit
8120
8130; -----------------------------------------------------------------------------
8140; an entry on the display menu has been selected
8150
8160.menu_display
8170 ldr r0,[r1,#4]
8180 cmp r0,#0 ; sort where clicked
8190 blt poll ; not menu item on click on display
8200 ; in main menu so poll again
8210 moveq r0,#1
8220 movgt r0,#0
8230 str r0,black_text_tick
8240
8250 strb r0,icon_text_colour
8260
8270 moveq r0,#&80
8280 movne r0,#&81
8290 str r0,white_text_tick
8300
8310 ldr r0,icon_flags
8320 bic r0,r0,#7 << 24
8330 eoreq r0,r0,#7 << 24
8340 str r0,icon_flags
8350
8360 adr r1,workspace+&800
8370 ldr r0,background_window_handle
8380 str r0,[r1,#-&800]!
8390 moveq r0,#7 << 24
8400 movne r0,#0
8410 str r0,[r1,#8]
8420 mov r0,#15 << 24
8430 str r0,[r1,#12]
8440 ldr r4,start_linked_list
8450 teq r4,#0 ; see if no icons at all
8460 beq see_if_reopen_menu
8470.menu_display_loop
8480 ldrb r0,[r4,#icon_handle]
8490 str r0,[r1,#4]
8500 swi "XWimp_SetIconState"
8510 bvs fatal_error
8520 ldr r4,[r4,#next]
8530 teq r4,#0
8540 bne menu_display_loop
8550 b see_if_reopen_menu
8560
8570; -----------------------------------------------------------------------------
8580; the remove menu option has been selected
8590
8600.remove
8610 adr r5,start_linked_list-&c00
8620 ldr r4,[r5,#&c00]!
8630.remove_loop
8640 ldr r6,[r4,#next] ; must be read here as freeing a block
8650 ; changes the value of [r4+next]
8660 ldrb r2,[r4,#selected]
8670 teq r2,#0
8680 streq r4,[r5,#next] ; store linked list pointer in last
8690 ; not removed data set if not removing
8700 moveq r5,r4 ; update last not removed data set
8710 ; pointer if not removing
8720 beq not_remove
8730 bl delete_icon
8740 bl free_heap_block
8750 ldrb r2,number_of_icons
8760 sub r2,r2,#1
8770 strb r2,number_of_icons
8780.not_remove
8790 movs r4,r6 ; move along list
8800 teq r4,#0 ; see if at end
8810 bne remove_loop
8820 str r4,[r5,#next] ; mark end of linked list
8830 strb r4,number_selected
8840 b see_if_reopen_menu
8850
8860; -----------------------------------------------------------------------------
8870; the select all menu option has been selected
8880
8890.select_all
8900 ldr r4,start_linked_list
8910.select_all_loop
8920 ldrb r2,[r4,#icon_handle]
8930 bl select_icon
8940 mov r2,#1
8950 strb r2,[r4,#selected]
8960 ldr r4,[r4]
8970 teq r4,#0
8980 bne select_all_loop
8990 ldrb r2,number_of_icons
9000 strb r2,number_selected
9010 b see_if_reopen_menu
9020
9030; -----------------------------------------------------------------------------
9040; the clear selecton menu option has been selected
9050
9060.clear_selection
9070 bl unselect_all
9080 b see_if_reopen_menu
9090
9100; -----------------------------------------------------------------------------
9110; the save backdrop menu entry has been selected.
9120
9130.save_backdrop
9140 mov r0,#&80
9150 adr r1,config_filename
9160 swi "XOS_Find"
9170 adrvs r14,poll+&800
9180 subvs r14,r14,#&800 ; cause it to return to poll loop
9190 bvs report_error_ok
9200 mov r1,r0 ; r1 = file handle
9210 ldrb r0,icon_text_colour ; store icon text colour
9220 swi "XOS_BPut"
9230 bvs error_while_writing
9240 ldrb r0,number_of_icons ; store number of icons
9250 swi "XOS_BPut"
9260 bvs error_while_writing
9270 ldr r2,start_linked_list
9280 teq r2,#0
9290 beq end_of_save
9300.save_backdrop_loop
9310 mov r0,#2 ; write bytes using current seq pointer
9320 ; r1 = file handle
9330 ldr r5,[r2,#next] ; get pointer to next entry
9340 ldr r3,[r2,#size]!
9350 sub r3,r3,#4
9360 swi "XOS_GBPB"
9370 bvs error_while_writing
9380 movs r2,r5 ; r2 -> next entry, set flags
9390 teq r2,#0
9400 bne save_backdrop_loop
9410.end_of_save
9420 mov r0,#2 ; write bytes using current seq pointer
9430 adr r2,zero ; r2 -> &00000000
9440 mov r3,#4
9450 swi "XOS_GBPB"
9460 bvs error_while_writing
9470 mov r0,#0 ; close file
9480 swi "XOS_Find"
9490 blvs report_error_ok
9500 b see_if_reopen_menu
9510.error_while_writing
9520 mov r2,r0 ; store error pointer
9530 mov r0,#0 ; close file
9540 swi "XOS_Find" ; ignore any errors
9550 mov r0,r2 ; restore error pointer
9560 bl report_error_ok
9570 b poll
9580.zero
9590 equd 0
9600.config_filename
9610 equs "<PlaceIt$Dir>.!Config"+CHR$0
9620 align
9630
9640; -----------------------------------------------------------------------------
9650; see if adjust was clicked on. if so reopen menu
9660
9670.see_if_reopen_menu
9680 ldr r0,pointer_info+8 ; r0 = button state
9690 tst r0,#1 ; see if adjust pressed
9700 beq poll ; wasn't so poll
9710 adr r1,pointer_info ; r1 -> click coordinates
9720 mvn r0,#0
9730 str r0,[r1,#16] ; no icon was clicked on
9740 b open_menu ; reopen menu
9750
9760.pointer_info
9770 equs STRING$(24,CHR$0)
9780
9790; -----------------------------------------------------------------------------
9800; The nice wimp has sent us a message
9810
9820.message
9830 ldr r11,[r1,#16] ; message ID
9840 teq r11,#0 ; see if closedown
9850 beq closedown_and_exit
9860 mov r0,#&c1
9870 add r0,r0,#&40000
9880 teq r11,r0 ; see if mode change message
9890 bleq read_screen_size ; this call preserves flags
9900 beq poll
9910 add r0,r0,#6 ; see if tasknameis
9920 teq r11,r0
9930 beq tasknameis
9940 teq r11,#2 ; see if datasaveack
9950 beq datasaveack
9960 teq r11,#4 ; see if dataloadack
9970 beq dataloadack
9980 teq r11,#3 ; see if dataload
9990 bne poll
10000
10010; -----------------------------------------------------------------------------
10020; we have received a dataload message. see if we can handle it
10030
10040.dataload
10050 ldr r0,[r1,#12] ; r0 = your_ref
10060 cmp r0,#0 ; check sent by filer
10070 bne poll ; poll if not
10080 ldr r3,[r1] ; r3 = length of message block
10090 sub r3,r3,#44-filename ; r3 = amount of storage needed
10100 bl get_heap_block
10110 teq r2,#0
10120 beq no_more_memory_error
10130 str r3,[r2,#size]
10140 adr r4,start_linked_list-&c00
10150 add r4,r4,#&c00
10160.dataload_loop1
10170 ldr r5,[r4,#next]
10180 teq r5,#0
10190 movne r4,r5
10200 bne dataload_loop1
10210 str r2,[r4,#next] ; store pointer to next data set
10220 str r5,[r2,#next] ; r5 = 0, mark next data set as last
10230 mov r4,r2
10240 ldr r0,[r1,#40] ; r0 = filetype of file to be loaded
10250 str r0,[r4,#filetype]
10260 add r0,r1,#44 ; r0 -> filename to be loaded
10270 add r2,r4,#filename
10280 sub r5,r2,r4
10290.dataload_loop2
10300 ldrb r3,[r0],#1
10310 strb r3,[r2],#1
10320 teq r3,#ASC"."
10330 subeq r5,r2,r4 ; r5 = offset to leafname
10340 teq r3,#0
10350 bne dataload_loop2
10360 str r5,[r4,#offset_to_leafname]
10370 add r5,r5,r4 ; r5 -> leafname, to use as sprite text
10380 mov r2,r1
10390 adr r1,workspace+&c00
10400 sub r1,r1,#&c00
10410 ldr r0,background_window_handle
10420 str r0,[r1]
10430 ldr r0,[r2,#28] ; r0 = x coordinate where drag ended
10440 sub r0,r0,#5*16
10450 str r0,[r1,#4] ; min x of icon
10460 str r0,[r4,#x_position]
10470 add r0,r0,#10*16
10480 str r0,[r1,#12] ; max x of icon
10490 ldr r0,[r2,#32] ; r0 = y coordinate where drag ended
10500 sub r0,r0,#54
10510 str r0,[r1,#8] ; min y of icon
10520 str r0,[r4,#y_position]
10530 add r0,r0,#108
10540 str r0,[r1,#16] ; max y of icon
10550 ldr r0,icon_flags
10560 str r0,[r1,#20]
10570 str r5,[r1,#24] ; store pointer to sprite text
10580 add r0,r4,#sprite_name
10590 str r0,[r1,#28] ; store pointer to validation string
10600 mov r2,#11
10610 str r2,[r1,#32]
10620 mov r2,#ASC"S"
10630 strb r2,[r0],#1
10640 ldr r3,[r4,#filetype]
10650 cmp r3,#&1000 ; see if has no filetype
10660 bge no_filetype
10670 mov r2,#ASC"f"
10680 strb r2,[r0],#1
10690 mov r2,#ASC"i"
10700 strb r2,[r0],#1
10710 mov r2,#ASC"l"
10720 strb r2,[r0],#1
10730 mov r2,#ASC"e"
10740 strb r2,[r0],#1
10750 mov r1,r0 ; r1 = buffer to store converted number
10760 mov r0,r3 ; r0 = filetype
10770 mov r2,#5 ; size of buffer
10780 swi "XOS_ConvertHex4"
10790 bvs fatal_error
10800 mov r2,#ASC"_"
10810 strb r2,[r0]
10820 sub r2,r0,#4 ; r2 -> sprite name
10830 bl see_if_sprite_exists
10840 movvs r0,r2 ; r0 -> where to put sprite name
10850 adrvs r2,file_xxx ; sprite wasn't found so use
10860 bvs no_filetype_loop ; file_xxx instead
10870 b finish_dataload
10880.application
10890 ldr r2,[r4,#offset_to_leafname]
10900 add r2,r2,r4
10910 bl see_if_sprite_exists
10920 adrvs r2,application_sprite ; use "application" as sprite name
10930 ; as sprite could not be found
10940 b no_filetype_loop
10950
10960.application_sprite
10970 equs "application"+CHR$0
10980.directory
10990 equs "directory"+CHR$0
11000.file_xxx
11010 equs "file_xxx"+CHR$0
11020 align
11030
11040.no_filetype
11050 cmp r3,#&2000
11060 adrlt r2,directory
11070 beq application
11080 adrgt r2,file_xxx
11090.no_filetype_loop
11100 ldrb r3,[r2],#1
11110 strb r3,[r0],#1
11120 teq r3,#0
11130 bne no_filetype_loop
11140
11150.finish_dataload
11160 adr r1,workspace+&c00
11170 sub r1,r1,#&c00
11180 swi "XWimp_CreateIcon"
11190 bvs fatal_error
11200 strb r0,[r4,#icon_handle]
11210 mov r0,#0
11220 strb r0,[r4,#selected]
11230 ldr r0,[r1] ; r0 = window handle
11240 ldr r2,[r1,#8] ; r2 = min y
11250 ldr r3,[r1,#12] ; r3 = max x
11260 ldr r4,[r1,#16] ; r4 = max y
11270 ldr r1,[r1,#4] ; r1 = min x
11280 swi "XWimp_ForceRedraw"
11290 bvs fatal_error
11300 ldrb r0,number_of_icons
11310 add r0,r0,#1
11320 strb r0,number_of_icons
11330 adr r1,poll_space+&c00
11340 sub r1,r1,#&c00
11350 ldr r0,[r1,#12]
11360 strb r0,[r1,#8]
11370 ldr r2,[r1,#4] ; reply to sender
11380 mov r0,#17 ; no reply needed
11390 swi "XWimp_SendMessage"
11400 bvs fatal_error
11410 b poll
11420
11430.no_more_memory_error
11440 adr r0,no_more_memory_error_block
11450 bl report_error_ok
11460 b poll
11470.no_more_memory_error_block
11480 equd 0
11490 equs "Not enough free memory"+CHR$0
11500 align
11510.icon_flags
11520 equd 1+(1 << 1)+(1 << 3)+(1 << 5)+(1 << 8)+(10 << 12)+(7 << 24)+(4 << 28)
11530
11540; -----------------------------------------------------------------------------
11550; we have received a datasaveack message
11560
11570.datasaveack
11580 ldr r0,[r1,#12]
11590 ldr r2,message_myref
11600 teq r0,r2 ; check we originated it
11610 bne poll
11620 swi "XHourglass_On" ; don't report errors as may have
11630 ; been unplugged
11640 mov r0,#26 ; copy
11650 add r2,r1,#44 ; r2 -> destination filename
11660 ldr r1,datasave_where_up_to
11670 add r1,r1,#filename ; r1 -> source filename
11680 mov r3,#1 ; flags for copy
11690 swi "XOS_FSControl"
11700 bvc copy_ok
11710 swi "XHourglass_Off" ; don't report errors as may have
11720 ; been unplugged
11730 bl report_error_ok
11740 b send_datasaveload_message_continue
11750.copy_ok
11760 swi "XHourglass_Off" ; don't report errors as may have
11770 ; been unplugged
11780 adr r1,poll_space+&c00
11790 sub r1,r1,#&c00
11800 ldr r0,[r1,#12]
11810 str r0,[r1,#8]
11820 mov r0,#3 ; dataload message
11830 str r0,[r1,#16]
11840 mov r0,#18 ; reply needed
11850 ldr r2,[r1,#4] ; reply to sender
11860 swi "XWimp_SendMessage"
11870 bvs fatal_error
11880 ldr r0,[r1,#8]
11890 str r0,message_myref
11900 b poll ; poll so that we receive reply
11910
11920; -----------------------------------------------------------------------------
11930; we have received a dataloadack message
11940
11950.dataloadack
11960 ldr r0,[r1,#12]
11970 ldr r2,message_myref
11980 teq r0,r2 ; check we originated it
11990 bne poll
12000 ldrb r0,delete_after_drag
12010 teq r0,#42 ; see if response to dataopen message
12020 beq poll ; if so just poll
12030 teq r0,#&ff ; see whether to delete icon
12040 ldreq r4,datasave_where_up_to
12050 ldr r0,[r4,#next] ; this will be changed by freeing heap
12060 ; block
12070 bleq remove_icon
12080 mov r4,r0
12090 adr r1,poll_space+&c00
12100 sub r1,r1,#&c00
12110 b send_datasaveload_message_continue2
12120
12130; -----------------------------------------------------------------------------
12140; see if a sprite exists in the wimp_sprite pool
12150; entry
12160; r2 -> sprite name
12170; exit
12180; v unset => sprite found
12190; set => sprite not found
12200
12210.see_if_sprite_exists
12220 stmfd r13!,{r0,r3-r6}
12230 mov r0,#40 ; read sprite info
12240 swi "XWimp_SpriteOp"
12250 ldmfd r13!,{r0,r3-r6}
12260 mov pc,r14
12270
12280; -----------------------------------------------------------------------------
12290; The nice wimp has sent us a message acknowledgement
12300
12310.message_acknowledged
12320 ldr r0,[r1,#8]
12330 ldr r2,message_myref
12340 cmp r0,r2 ; see if one our message
12350 bne poll ; poll otherwise, can this happen ?
12360 ldr r0,[r1,#16]
12370 teq r0,#1 ; see if datasave message
12380 beq datasave_not_acknowledged
12390 teq r0,#3 ; see if dataload message
12400 beq dataload_not_acknowledged
12410 teq r0,#5 ; see if dataopen message
12420 bne poll ; if not poll
12430 ldr r0,[r1,#40] ; get filetype
12440 cmp r0,#&1000 ; see if directory
12450 adreq r2,filer_opendir_command
12460 adrne r2,run_command
12470 add r0,r1,#30 ; r0 -> where to put command
12480.message_ack_loop
12490 ldrb r3,[r2],#1
12500 teq r3,#0
12510 strneb r3,[r0],#1
12520 bne message_ack_loop
12530 add r0,r1,#30 ; r0 -> command
12540 swi "XWimp_StartTask"
12550 bvs fatal_error
12560 b poll
12570.filer_opendir_command
12580 equs "Filer_OpenDir "+CHR$0
12590.run_command
12600 equs "Run "+CHR$0
12610 align
12620
12630.datasave_not_acknowledged
12640 beq send_datasaveload_message_continue
12650
12660.dataload_not_acknowledged
12670 b send_datasaveload_message_continue
12680
12690; -----------------------------------------------------------------------------
12700; heap handling routines
12710
12720; -----------------------------------------------------------------------------
12730; get a heap block. If fails try and extend wimp_slot
12740; entry
12750; r3 = size wanted
12760; exit
12770; r2 -> heap block if succeeded
12780; r2 = 0 if failed, r3 corrupted in this case
12790
12800.get_heap_block
12810 stmfd r13!,{r0-r1,r4-r6,r14}
12820 mov r6,r3
12830 mov r0,#2 ; get heap block
12840 adr r1,heap_start-&800
12850 add r1,r1,#&800
12860 swi "XOS_Heap"
12870 ldmvcfd r13!,{r0-r1,r4-r6,pc} ; if succeeded return
12880 mvn r0,#0
12890 mov r1,r0
12900 swi "XWimp_SlotSize"
12910 bvs fatal_error
12920 mov r5,r0 ; store old size
12930 add r0,r0,#8*1024 ; we want some more memory
12940 mvn r1,#0
12950 swi "XWimp_SlotSize"
12960 movvs r2,#0 ; r2 = 0 if failed
12970 ldmvsfd r13!,{r0-r1,r4-r6,pc} ; then return
12980 sub r3,r0,r5 ; r3 = amount of new memory we got
12990 adr r1,heap_start-&800
13000 add r1,r1,#&800
13010 mov r0,#5 ; extend heap
13020 swi "XOS_Heap"
13030 bvs fatal_error
13040 mov r0,#2 ; get heap block
13050 mov r3,r6
13060 swi "XOS_Heap"
13070 bvs fatal_error ; we should succeed this time
13080 ldmfd r13!,{r0-r1,r4-r6,pc}
13090
13100; -----------------------------------------------------------------------------
13110; free a heap block
13120; entry
13130; r4 -> heap block
13140
13150.free_heap_block
13160 stmfd r13!,{r0-r2}
13170 mov r0,#3 ; free heap block
13180 adr r1,heap_start-&400
13190 add r1,r1,#&400
13200 mov r2,r4
13210 swi "XOS_Heap"
13220 bvs fatal_error
13230 ldmfd r13!,{r0-r2}
13240 mov pc,r14
13250
13260; -----------------------------------------------------------------------------
13270; search the linked list for an icon
13280; entry
13290; r2 = icon handle
13300; exit
13310; r4 -> data entry in linked list
13320
13330.find_icon
13340 stmfd r13!,{r3}
13350 ldr r4,start_linked_list
13360.find_icon_loop
13370 ldrb r3,[r4,#icon_handle]
13380 teq r3,r2
13390 ldmeqfd r13!,{r3}
13400 moveq pc,r14
13410 ldr r4,[r4,#next]
13420 b find_icon_loop
13430
13440; -----------------------------------------------------------------------------
13450; select an icon on the background
13460; entry
13470; r2 = icon handle
13480
13490.select_icon
13500 stmfd r13!,{r1,r3}
13510 adr r1,workspace+&1000
13520 sub r1,r1,#&1000
13530 ldr r3,background_window_handle
13540 str r3,[r1]
13550 str r2,[r1,#4]
13560 mov r3,#1 << 21
13570 str r3,[r1,#8]
13580 str r3,[r1,#12]
13590 swi "XWimp_SetIconState"
13600 bvs fatal_error
13610 ldmfd r13!,{r1,r3}
13620 movs pc,r14
13630
13640; -----------------------------------------------------------------------------
13650; unselect the sprite selected by menu
13660
13670.unselect_menu_selected_icon
13680 stmfd r13!,{r3-r4,r14}
13690 ldr r4,start_linked_list
13700.unselect_menu_selected_icon_loop
13710 ldrb r3,[r4,#selected]
13720 teq r3,#2 ; see if menu selected
13730 ldrne r4,[r4,#next]
13740 bne unselect_menu_selected_icon_loop
13750 bl unselect_icon
13760 mov r3,#0
13770 strb r3,number_selected
13780 ldmfd r13!,{r3-r4,pc}
13790
13800; -----------------------------------------------------------------------------
13810; unselect an icon on the background. and unsets flags in data entry
13820; entry
13830; r4 -> data_entry
13840
13850.unselect_icon
13860 stmfd r13!,{r1,r3}
13870 ldrb r3,[r4,#selected]
13880 teq r3,#1 ; see if selected
13890 ldmnefd r13!,{r1,r3} ; not so restore r1,r3
13900 movnes pc,r14 ; then return
13910 adr r1,workspace+&1000
13920 sub r1,r1,#&1000
13930 ldr r3,background_window_handle
13940 str r3,[r1]
13950 ldrb r3,[r4,#icon_handle]
13960 str r3,[r1,#4]
13970 mov r3,#0
13980 str r3,[r1,#8]
13990 mov r3,#1 << 21
14000 str r3,[r1,#12]
14010 swi "XWimp_SetIconState"
14020 bvs fatal_error
14030 mov r3,#0
14040 strb r3,[r4,#selected] ; store as unselected
14050 ldmfd r13!,{r1,r3}
14060 movs pc,r14
14070
14080; -----------------------------------------------------------------------------
14090; unselect all icons and set number of selected icons to zero
14100
14110.unselect_all
14120 stmfd r13!,{r2,r4,r14}
14130 ldr r4,start_linked_list
14140 teq r4,#0 ; see if no icons exist
14150 ldmeqfd r13!,{r2,r4,pc} ; if so return
14160.clear_selection_loop
14170 bl unselect_icon
14180 ldr r4,[r4]
14190 teq r4,#0
14200 bne clear_selection_loop
14210 strb r4,number_selected
14220 ldmfd r13!,{r2,r4,pc}^
14230
14240; -----------------------------------------------------------------------------
14250; This routine reads the screen size in external coordinates
14260
14270.read_screen_size
14280 stmfd r13!,{r14}
14290 mvn r0,#0 ; read about current mode
14300 mov r1,#4 ; r1 = XEigFactor
14310 swi "XOS_ReadModeVariable"
14320 bvs fatal_error
14330 mov r3,r2
14340 mov r1,#11 ; r1 = XWindLimit
14350 swi "XOS_ReadModeVariable"
14360 bvs fatal_error
14370 mov r2,r2,lsl r3
14380 str r2,screen_maxx
14390 str r2,workarea_maxx
14400 mov r1,#5 ; r1 = YEigFactor
14410 swi "XOS_ReadModeVariable"
14420 bvs fatal_error
14430 mov r3,r2
14440 mov r1,#12 ; r1 = YWindLimit
14450 swi "XOS_ReadModeVariable"
14460 bvs fatal_error
14470 mov r2,r2,lsl r3
14480 str r2,screen_maxy
14490 str r2,workarea_maxy
14500 str r2,scroll_y
14510 mov r0,#1
14520 strb r0,mode_changed
14530 ldmfd r13!,{pc}^ ; preserve flags
14540
14550; -----------------------------------------------------------------------------
14560; closedown and exit
14570
14580.closedown_and_exit
14590 bl closedown
14600 swi "OS_Exit"
14610
14620; -----------------------------------------------------------------------------
14630; either we could not start up, the user wants us to closedown or we have
14640; had a module finalisation call
14650
14660.closedown
14670 adr r1,task_handle+&1000
14680 sub r1,r1,#&1000
14690 ldr r0,[r1]
14700 ldr r1,[r1,#task-task_handle]
14710 swi "XWimp_CloseDown" ; close down if so
14720 mov pc,r14
14730
14740; -----------------------------------------------------------------------------
14750; misc flags and data
14760
14770.mode_changed
14780 equb 0
14790.icon_text_colour
14800 equb 1
14810.delete_after_drag
14820 equb 0
14830.number_of_icons
14840 equb 0
14850.number_selected
14860 equb 0
14870.save_to_filer
14880 equb 0
14890 align
14900.button_state
14910.heap_entry_length
14920.message_myref
14930 equd 0
14940
14950; -----------------------------------------------------------------------------
14960; define the background window. v set if error occurred
14970
14980.define_background_window
14990 stmfd r13!,{r14}
15000 bl read_screen_size
15010 adr r1,background_window
15020 swi "XWimp_CreateWindow"
15030 ldmvsfd r13!,{pc}
15040 adr r1,background_window_handle
15050 str r0,[r1]
15060 swi "XWimp_OpenWindow"
15070 ldmfd r13!,{pc}
15080
15090; -----------------------------------------------------------------------------
15100; background window data block
15110
15120.background_window_handle
15130 equd 0
15140.background_window
15150 equd 0
15160 equd 136
15170.screen_maxx
15180 equd 0
15190.screen_maxy
15200 equd 0
15210 equd 0
15220.scroll_y
15230 equd 0
15240 equd -2 ; open at bottom
15250 equd (1 << 4)+(1 << 11)+(1 << 31)
15260 equb &ff
15270 equb 0
15280 equb 7
15290 equb 4 ; window background colour
15300 equb 0
15310 equb 0
15320 equb 0
15330 equb 0
15340.workarea_coords
15350 equd 0
15360 equd 136
15370.workarea_maxx
15380 equd 0
15390.workarea_maxy
15400 equd 0
15410 equd 0
15420 equd 3 << 12 ; workarea button type = 3
15430 equd 1 ; use wimp sprite area
15440 equd 0
15450 equs STRING$(12,CHR$0) ; no title
15460 equd 0 ; no icons defined orignally
15470
15480; -----------------------------------------------------------------------------
15490; define the info window and store it's handle. v set if error occured
15500
15510.define_info_window
15520 stmfd r13!,{r14}
15530 adr r1,info_window
15540 swi "XWimp_CreateWindow"
15550 strvc r0,info_window_handle
15560 ldmfd r13!,{pc} ; v will be set if error occured
15570
15580; -----------------------------------------------------------------------------
15590; information about info window
15600
15610.window_title
15620 equs "About this program"+CHR$0
15630.end_window_title
15640 align
15650.name
15660 equs "Place It"+CHR$0
15670.end_name
15680 align
15690.purpose
15700 equs "Place files on the backdrop"+CHR$0
15710.end_purpose
15720 align
15730.author
15740 equs "pmf@uk.ac.warwick.cs"+CHR$0
15750.end_author
15760 align
15770.version
15780 equs "1.03 (19-Jan-91)"+CHR$0
15790.end_version
15800 align
15810
15820.info_window
15830 equd 0
15840 equd 0
15850 equd 636
15860 equd 216
15870 equd 0
15880 equd 0
15890 equd -1
15900 equd (1 << 31)+(1 << 26)+(1 << 4)+(1 << 1)
15910 equb 7
15920 equb 2
15930 equb 7
15940 equb 1
15950 equd 0
15960 equd 0
15970 equd -216
15980 equd 636
15990 equd 0
16000 equd (1 << 8)+(1 << 4)+(1 << 3)+1
16010 equd 0
16020 equd 0
16030 equd 0
16040 equd window_title
16050 equd -1
16060 equd end_window_title-window_title
16070 equd 8
16080 equd 58
16090 equd -48
16100 equd 154
16110 equd -8
16120 equd (&17 << 24)+(1 << 4)+(1 << 3)+1
16130 FNstring("Name")
16140 equd 14
16150 equd -100
16160 equd 154
16170 equd -60
16180 equd (&17 << 24)+(1 << 4)+(1 << 3)+1
16190 FNstring("Purpose")
16200 equd 30
16210 equd -152
16220 equd 154
16230 equd -112
16240 equd (&17 << 24)+(1 << 4)+(1 << 3)+1
16250 FNstring("Author")
16260 equd 14
16270 equd -200
16280 equd 154
16290 equd -160
16300 equd (&17 << 24)+(1 << 4)+(1 << 3)+1
16310 FNstring("Version")
16320 equd 154
16330 equd -52
16340 equd 630
16350 equd -4
16360 equd (7 << 24)+(1 << 8)+(1 << 5)+(1 << 4)+(1 << 3)+(1 << 2)+1
16370 equd name
16380 equd -1
16390 equd end_name-name
16400 equd 154
16410 equd -104
16420 equd 630
16430 equd -56
16440 equd (7 << 24)+(1 << 8)+(1 << 5)+(1 << 4)+(1 << 3)+(1 << 2)+1
16450 equd purpose
16460 equd -1
16470 equd end_purpose-purpose
16480 equd 154
16490 equd -156
16500 equd 630
16510 equd -108
16520 equd (7 << 24)+(1 << 8)+(1 << 5)+(1 << 4)+(1 << 3)+(1 << 2)+1
16530 equd author
16540 equd -1
16550 equd end_author-author
16560 equd 154
16570 equd -208
16580 equd 630
16590 equd -160
16600 equd (7 << 24)+(1 << 8)+(1 << 5)+(1 << 4)+(1 << 3)+(1 << 2)+1
16610 equd version
16620 equd -1
16630 equd end_version-version
16640
16650; -----------------------------------------------------------------------------
16660; set initial conditions
16670
16680.set_initial_conditions
16690 mvn r0,#0
16700 mov r1,r0
16710 swi "XWimp_SlotSize"
16720 movvs pc,r14
16730 adr r1,heap_start
16740 sub r3,r0,r1
16750 add r3,r3,#&8000 ; r3 = amount of memory spare
16760 mov r0,#0 ; initialise heap
16770 str r0,start_linked_list
16780 swi "XOS_Heap"
16790 mov pc,r14 ; return with v set accordingly
16800
16810; -----------------------------------------------------------------------------
16820; load the !Config file if it exists
16830
16840.load_config_file
16850 stmfd r13!,{r14}
16860 mov r0,#&47 ; open file, complain if is a directory
16870 ; no search path
16880 adr r1,config_filename+&800
16890 sub r1,r1,#&800
16900 swi "XOS_Find"
16910 ldmvsfd r13!,{pc}
16920 movs r1,r0 ; r1 = filehandle, set flags
16930 ldmeqfd r13!,{pc} ; if file not found return
16940 swi "XOS_BGet" ; get icon text colour
16950 bvs read_error
16960 bcs config_file_ended_unexpectedly
16970 strb r0,icon_text_colour
16980 str r0,black_text_tick
16990
17000 rsb r2,r0,#&81
17010 str r2,white_text_tick
17020
17030 teq r0,#0 ; see if icon text white
17040 ldreq r0,icon_flags
17050 biceq r0,r0,#7 << 24 ; see text colour white
17060 streq r0,icon_flags
17070
17080 swi "XOS_BGet" ; get number of icons
17090 bvs read_error
17100 bcs config_file_ended_unexpectedly
17110 strb r0,number_of_icons
17120 adr r5,start_linked_list
17130 teq r0,#0
17140 beq load_config_file_done
17150
17160.load_config_file_loop
17170 mov r0,#4 ; read bytes using current csp
17180 adr r2,heap_entry_length
17190 mov r3,#4 ; read four bytes
17200 swi "XOS_GBPB"
17210 bvs read_error
17220 bcs config_file_ended_unexpectedly
17230 ldr r3,heap_entry_length
17240 teq r3,#0
17250 beq load_config_file_done
17260 bl get_heap_block
17270 teq r2,#0
17280 adreq r0,ran_out_of_memory_during_load
17290 beq read_error
17300 str r2,[r5,#next] ; store pointer to next data set
17310 mov r5,r2 ; update previous data set pointer
17320 str r3,[r2,#size]
17330 add r2,r2,#offset_to_leafname ; skip next ans size entries
17340 sub r3,r3,#offset_to_leafname ; in linked list entry
17350 swi "XOS_GBPB"
17360 bvs read_error
17370 bcs config_file_ended_unexpectedly
17380 b load_config_file_loop
17390
17400.load_config_file_done
17410 mov r0,#0
17420 strb r0,number_selected ; no icons selected
17430 str r0,[r5,#next] ; mark end of linked list
17440 mov r0,#0
17450 swi "XOS_Find"
17460 blvs report_error_ok
17470 ldr r4,start_linked_list
17480 teq r4,#0
17490 ldmeqfd r13!,{pc}
17500
17510.load_config_file_loop2
17520 mov r0,#0
17530 strb r0,[r4,#selected] ; mark icon as unselected
17540 ldr r0,[r4,#filetype]
17550 teq r0,#&2000 ; see if application
17560 bleq boot_application
17570 ldr r4,[r4,#next]
17580 teq r4,#0
17590 bne load_config_file_loop2
17600
17610 ldr r4,start_linked_list
17620 adr r1,workspace+&1400
17630 sub r1,r1,#&1400
17640 ldr r0,background_window_handle
17650 str r0,[r1]
17660.load_config_file_loop3
17670 ldr r0,[r4,#x_position]
17680 str r0,[r1,#4]
17690 add r0,r0,#10*16
17700 str r0,[r1,#12]
17710 ldr r0,[r4,#y_position]
17720 str r0,[r1,#8]
17730 add r0,r0,#108
17740 str r0,[r1,#16]
17750 ldr r0,icon_flags
17760 str r0,[r1,#20]
17770 ldr r0,[r4,#offset_to_leafname]
17780 add r0,r0,r4
17790 str r0,[r1,#24]
17800 add r0,r4,#sprite_name
17810 str r0,[r1,#28]
17820 mov r0,#12
17830 str r0,[r1,#32]
17840 swi "XWimp_CreateIcon"
17850 ldmvsfd r13!,{pc}
17860 strb r0,[r4,#icon_handle]
17870 ldr r4,[r4,#next]
17880 teq r4,#0
17890 bne load_config_file_loop3
17900 ldmfd r13!,{pc}
17910
17920.read_error
17930 mov r2,r0 ; store error pointer
17940 mov r0,#0 ; close file
17950 swi "XOS_Find" ; ignore errors
17960 mov r0,r2 ; restore error pointer
17970 bl report_error_ok
17980 ldmfd r13!,{pc}
17990
18000.config_file_ended_unexpectedly
18010 adr r0,config_file_ended_unexpectedly_error
18020 b read_error
18030.config_file_ended_unexpectedly_error
18040 equd 0
18050 equs "The config file ended unexpectedly. I recommend deleting the "
18060 equs "config file and starting again"+CHR$0
18070 align
18080
18090.ran_out_of_memory_during_load
18100 equd 0
18110 equs "Ran out of memory during load. I recomend you quit me"+CHR$0
18120 align
18130
18140; -----------------------------------------------------------------------------
18150; run a the !Boot file in the application directory
18160; if this can't be found do *IconSprites !Sprites instead
18170; entry
18180; r4 -> linked list entry
18190
18200.boot_application
18210 stmfd r13!,{r0-r3,r5-r7,r14}
18220 add r2,r4,#sprite_name+1
18230 bl see_if_sprite_exists
18240 ldmvcfd r13!,{r0-r3,r5-r7,pc} ; sprite exists so return
18250 adr r0,poll_space+&1400+4 ; +4 to allow for "Run " infront
18260 sub r0,r0,#&1400
18270 add r1,r4,#filename
18280.boot_application_loop
18290 ldrb r2,[r1],#1
18300 strb r2,[r0],#1
18310 teq r2,#0
18320 bne boot_application_loop
18330 mov r2,#ASC"."
18340 strb r2,[r0,#-1] ; replace CHR$0 with "."
18350 mov r7,r0 ; store leafname pointer
18360 adr r1,pling_boot ; r1 -> !Boot
18370.boot_application_loop2
18380 ldrb r2,[r1],#1
18390 strb r2,[r0],#1
18400 teq r2,#0
18410 bne boot_application_loop2
18420 mov r0,#17 ; read catalogue info no path
18430 adr r1,poll_space+&1400+4
18440 sub r1,r1,#&1400
18450 mov r6,r4 ; preserve r4
18460 swi "XOS_File"
18470 mov r4,r6 ; restore r4
18480 bvc catalogue_read_ok
18490 bl report_error_ok
18500 ldmfd r13!,{r0-r3,r5-r7,pc}
18510.catalogue_read_ok
18520 teq r0,#0 ; see if object found
18530 beq pling_boot_not_found
18540 adr r0,poll_space+&1400
18550 sub r0,r0,#&1400
18560 ldr r2,run ; r2 = "Run "
18570 str r2,[r0]
18580 swi "XWimp_StartTask"
18590 bvs fatal_error
18600 ldmfd r13!,{r0-r3,r5-r7,pc}
18610.run
18620 equs "Run "
18630
18640.pling_boot_not_found
18650 adr r1,pling_sprites ; r1 -> !Sprites
18660.boot_application_loop3
18670 ldrb r2,[r1],#1
18680 strb r2,[r7],#1
18690 teq r2,#0
18700 bne boot_application_loop3
18710 mov r0,#11 ; merge sprites (ie *IconSprites)
18720 adr r2,poll_space+&1400+4
18730 sub r2,r2,#&1400
18740 swi "XWimp_SpriteOp"
18750 blvs report_error_ok
18760 ldmfd r13!,{r0-r3,r5-r7,pc}
18770
18780.pling_boot
18790 equs "!Boot"+CHR$0
18800.pling_sprites
18810 equs "!Sprites"+CHR$0
18820 align
18830
18840; -----------------------------------------------------------------------------
18850; report an error using Wimp_ReportError then closedown
18860; entry
18870; r0 -> error block
18880; exit
18890; doesn't
18900
18910.fatal_error
18920 adr r1,poll_space+&1800
18930 sub r1,r1,#&1800
18940 ldr r2,[r0],#4
18950 str r2,[r1],#4
18960 adr r2,fatal_error_message
18970.fatal_error_loop1
18980 ldrb r3,[r2],#1
18990 cmp r3,#0
19000 strneb r3,[r1],#1
19010 bne fatal_error_loop1
19020.fatal_error_loop2
19030 ldrb r3,[r0],#1
19040 cmp r3,#0
19050 strneb r3,[r1],#1
19060 bne fatal_error_loop2
19070.fatal_error_loop3
19080 ldrb r3,[r2],#1
19090 strb r3,[r1],#1
19100 cmp r3,#0
19110 bne fatal_error_loop3
19120 adr r0,poll_space+&1800
19130 sub r0,r0,#&1800
19140 mov r1,#2 ; cancel only
19150 bl report_error
19160 bl closedown
19170 swi "OS_Exit"
19180.fatal_error_message
19190 equs "PlaceIt has suffered a fatal internal error ("+CHR$0
19200 equs ") and must exit immediately"+CHR$0
19210 align
19220
19230; -----------------------------------------------------------------------------
19240; report an error using Wimp_ReportError
19250; entry
19260; r0 -> error block
19270; r1 = flags for error window
19280; bit 0 set ==> provide 'OK' box in error window
19290; bit 1 set ==> provide 'Cancel' box
19300; bit 2 set ==> highlight 'Cancel' box (otherwise highlight 'OK')
19310; bit 3 set ==> don't wait for confirmation if this is a 'text' error
19320; bit 4 set ==> omit 'Error from ' message in title bar
19330; bit 5 set ==> return with r1=0 immediately if buttons not clicked
19340; the error window is also left open
19350; bit 6 set ==> select OK/Cancel depending on r1, close error window
19360; bits 7..31 reserved (must be 0)
19370; exit
19380; r1 = return status
19390; 1 ==> 'OK' was selected
19400; 2 ==> 'Cancel' was selected
19410; flags preserved
19420; r2 corrupted
19430
19440.report_error_ok
19450 mov r1,#1
19460.report_error
19470 stmfd r13!,{r14}
19480 adr r2,switcher_name+&1800
19490 sub r2,r2,#&1800 ; r2 -> "PlaceIt"
19500 swi "Wimp_ReportError"
19510 ldmfd r13!,{pc}^ ; preserve flags
19520
19530; -----------------------------------------------------------------------------
19540; information about the linked list and heap
19550
19560.start_linked_list
19570 equd 0
19580.heap_start
19590]
19600NEXT
19610PRINT ~O%-code%;" = ";(O%-code%)/1024;" K"
19620OSCLI "Save !RunImage "+STR$~code%+" "+STR$~O%
19630*SetType !RunImage Absolute
19640*Key 1 TWINO 8|M
19650*Key 2 Load !PlaceIt|M
19660*Key 3 SAVE|MRUN|M
19670*Key 4 *DeskTop|M
19680END
19690
19700DEF FNstring(text$)
19710IF LEN(text$)>12 THEN ERROR 0,text$+" is longer than 12 characters"
19720[ opt opt%
19730 equs text$
19740]
19750IF LEN(text$)<12 THEN
19760[ opt opt%
19770 equs STRING$(12-LEN(text$),CHR$0)
19780]
19790ENDIF
19800=0
� > !PlaceIt
7� by Ian Ashley (pmf@uk.ac.warwick.cs) on 6/10/90
!� Update to 1.03 on 19/1/91
(
22space%=&2000 : � 8K
<
Fv_flag=1 << 28
P
Zstacklen% = 32
d
nE� format of each data entry in the linked list (stored as a heap)
x
� next = 0
� size = 4
� offset_to_leafname = 8
�!icon_handle = 12
�!selected = 13
�!x_position = 16
�!y_position = 20
�!sprite_name = 24
�!filetype = 40
�!filename = 44
�
�)� needed to stop errors on first pass
�
$background_window_handle = &9000
$mode_changed = &9000
$number_selected = &9400
"$start_linked_list = &9800
,0heap_start = start_linked_list
6
@� code% space%
J
T� opt%=12 � 14 � 2
^P%=&8000
hO%=code%
rHL%=code%+space% : � Upper limit for assembly
|[
� opt opt%
� adr r13,stack
� ldr r1,task
�B mov r0,#200 ; last known wimp 2.00
�> adr r2,switcher_name ; r2 -> "Place It"
�& swi "XWimp_Initialise"
�! bvs startup_error
�" str r1,task_handle
�! bvs startup_error
�, bl define_background_window
�! bvs startup_error
�& bl define_info_window
�! bvs startup_error
* bl set_initial_conditions
! bvs startup_error
$ bl load_config_file
&! bvs startup_error
0 b poll
:
D.switcher_name
N equs "Place It"
X equb 0
b align
l.task_handle
v equd 0
� .task
� equs "TASK"
�
�S; -----------------------------------------------------------------------------
�N; report an error using Wimp_ReportError, set could not start up flag then
�; closedown
�; entry
�; r0 -> error block
�
; exit
�; doesn't
�
�.startup_error
�! adr r1,poll_space
ldr r2,[r0],#4
str r2,[r1],#4
, adr r2,startup_error_message
.startup_error_loop1
* ldrb r3,[r2],#1
4 cmp r3,#0
> strneb r3,[r1],#1
H' bne startup_error_loop1
R.startup_error_loop2
\ ldrb r3,[r0],#1
f cmp r3,#0
p strneb r3,[r1],#1
z' bne startup_error_loop2
�.startup_error_loop3
� ldrb r3,[r2],#1
� strb r3,[r1],#1
� cmp r3,#0
�' bne startup_error_loop3
�! adr r0,poll_space
�9 mov r1,#2 ; cancel only
� bl report_error
� bl closedown
� swi "OS_Exit"
�.startup_error_message
�4 equs "PlaceIt could not startup ("+�0
�4 equs ") and must exit immediately"+�0
align
S; -----------------------------------------------------------------------------
$%; poll space, workspace and stack
.
8.poll_space
B equs �128,�0)
L equs �128,�0)
V.workspace
` equs �60,�0)
j.stack_start
t" equs �stacklen%,�0)
~
.stack
�
�S; -----------------------------------------------------------------------------
�; wimp poll loop
�
� .poll
�2 mov r0,#%110001 ; Mask
�! adr r1,poll_space
� swi "XWimp_Poll"
� bvs fatal_error
� teq r0,#1
�! beq redraw_window
� teq r0,#2
beq open_window
teq r0,#3
beq close_window
teq r0,#6
( beq mouse_button
2 teq r0,#7
< beq drag_end
F teq r0,#9
P beq menu_select
Z teq r0,#17
d teqne r0,#18
n beq message
x teq r0,#19
�( beq message_acknowledged
� b poll
�
�S; -----------------------------------------------------------------------------
�); redraw window request has been sent
�
�.redraw_window
�( swi "XWimp_RedrawWindow"
� bvs fatal_error
� b poll
�
�S; -----------------------------------------------------------------------------
�'; open window request has been sent
.open_window
) adr r2,mode_changed-&1000
" add r2,r2,#&1000
, ldrb r0,[r2]
6J teq r0,#1 ; see if mode has just changed
@5 adreq r1,background_window_handle-&1000
J addeq r1,r1,#&1000
T moveq r0,#0
^ streqb r0,[r2]
h& swi "XWimp_OpenWindow"
r bvs fatal_error
| b poll
�
�S; -----------------------------------------------------------------------------
�(; close window request has been sent
�
�.close_window
�' swi "XWimp_CloseWindow"
� bvs fatal_error
� b poll
�
�S; -----------------------------------------------------------------------------
�'; mouse click request has been sent
�
�.mouse_button
G ldr r0,[r1,#12] ; r0=window handle of click
5 adr r2,background_window_handle-&1000
add r2,r2,#&1000
& ldr r2,[r2]
0C cmp r0,r2 ; is it on our window ?
:9 bne poll ; poll if not
D= ldr r0,[r1,#8] ; r0=button state
NJ tst r0,#2 ; see if middle button clicked
X= bne open_menu ; if so open menu
bG ldr r2,[r1,#16] ; r2=icon handle clicked on
l@ cmn r2,#1 ; see if not on icon
vP moveq r0,r0,lsl #8 ; if shift button state to right pos
�K tst r0,#%101 ; see if button doubled clicked
�" bne double_clicked
�A tst r0,#%101 * 16 ; see if drag started
� bne drag_started
�C tst r0,#%001 * 256 ; see if adjust clicked
�" bne adjust_clicked
�.select_clicked
�@ cmn r2,#1 ; see if on workarea
�@ bleq unselect_all ; if so unselect all
�7 beq poll ; then poll
� bl find_icon
�% ldrb r3,[r4,#selected]
�= teq r3,#1 ; see if selected
8 beq poll ; if so poll
bl unselect_all
9 bl select_icon ; select icon
mov r2,#1
*, adr r3,number_selected-&1000
4 add r3,r3,#&1000
> strb r2,[r3]
H% strb r2,[r4,#selected]
R b poll
\.adjust_clicked
f@ cmn r2,#1 ; see if on workarea
p8 beq poll ; if so poll
z bl find_icon
�% ldrb r3,[r4,#selected]
�D teq r3,#1 ; see if icon unselected
�A ; or selected by menu
� blne select_icon
�! bleq unselect_icon
� movne r3,#1
� moveq r3,#0
�% strb r3,[r4,#selected]
�, adr r4,number_selected-&1000
� add r4,r4,#&1000
� ldrb r3,[r4]
� addne r3,r3,#1
� subeq r3,r3,#1
strb r3,[r4]
b poll
.drag_started
$H teq r0,#1 * 16 ; see if adjust used in drag
. moveq r0,#&ff
8 movne r0,#0
B( strb r0,delete_after_drag
L ldmia r1,{r0,r2}
V# str r0,drag_x_start
`# str r2,drag_y_start
j; mov r0,#129 ; scan keyboard
tB mov r1,#&ff ; scan for both shifts
~ mov r2,r1
� swi "XOS_Byte"
� bvs fatal_error
�I teq r2,#&ff ; see if either shift pressed
�N streqb r2,delete_after_drag ; if so store so as know to delete
�I ; icon when drag has finished
�! adr r1,poll_space
� ldr r2,[r1,#16]
� bl find_icon
�% ldrb r0,[r4,#selected]
�E teq r0,#1 ; see if already selected
� movne r0,#1
�% strneb r0,[r4,#selected]
& ldrneb r0,number_selected
addne r0,r0,#1
& strneb r0,number_selected
blne select_icon
( adr r1,workspace
2J mov r0,#5 ; drag fixed size rotating box
< str r0,[r1,#4]
FP ldr r2,screen_maxx ; r2 will be min x of selected icons
PP ldr r3,screen_maxy ; r3 will be min y of selected icons
ZP mov r4,#0 ; r4 will be max x of selected icons
dP mov r5,r4 ; r5 will be min y of selected icons
n. adr r6,start_linked_list-&1400
x add r6,r6,#&1400
� ldr r6,[r6]
�.drag_started_loop
�% ldrb r0,[r6,#selected]
� teq r0,#0
�* beq drag_started_loop_skip
�' ldr r0,[r6,#x_position]
� cmp r0,r2
� movlt r2,r0
� cmp r0,r4
� movgt r4,r0
�' ldr r0,[r6,#y_position]
� cmp r0,r3
� movlt r3,r0
cmp r0,r5
movgt r5,r0
.drag_started_loop_skip
"! ldr r6,[r6,#next]
, teq r6,#0
6% bne drag_started_loop
@ sub r2,r2,#8
J str r2,[r1,#8]
T sub r3,r3,#4
^ str r3,[r1,#12]
h! add r4,r4,#160+10
r str r4,[r1,#16]
| add r5,r5,#108+4
� str r5,[r1,#20]
�
�! adr r6,drag_x_min
�A stmia r6,{r2-r5} ; store for later use
�
�# ldr r6,drag_x_start
�# ldr r7,drag_y_start
�
�" ldr r0,screen_maxx
� sub r0,r0,r6
� add r0,r0,r4
�A str r0,[r1,#32] ; max x of parent box
�
" ldr r0,screen_maxy
sub r0,r0,r7
add r0,r0,r5
&A str r0,[r1,#36] ; max y of parent box
0
: sub r0,r2,r6
DA str r0,[r1,#24] ; min x of parent box
N
X sub r0,r3,r7
bA str r0,[r1,#28] ; min y of parent box
l
v# swi "XWimp_DragBox"
� bvs fatal_error
� b poll
�.drag_x_start
� equd 0
�.drag_y_start
� equd 0
�.drag_x_min
� equd 0
�.drag_y_min
� equd 0
�.drag_x_max
� equd 0
�.drag_y_max
equd 0
.double_clicked
# str r0,button_state
mov r3,r2
*; mov r0,#129 ; scan keyboard
4B mov r1,#&ff ; scan for both shifts
> mov r2,r1
H swi "XOS_Byte"
R bvs fatal_error
\ mov r5,r2
f mov r2,r3
p bl find_icon
z% ldrb r3,[r4,#selected]
�= teq r3,#1 ; see if selected
�! bleq unselect_icon
�& ldreqb r3,number_selected
� subeq r3,r3,#1
�& streqb r3,number_selected
�& adr r1,poll_space+&400
� sub r1,r1,#&400
�> mov r0,#5 ; dataopen message
� str r0,[r1,#16]
�/ ldr r0,background_window_handle
� str r0,[r1,#20]
�' ldr r0,[r4,#x_position]
� str r0,[r1,#28]
' ldr r0,[r4,#y_position]
str r0,[r1,#32]
L mov r0,#0 ; we are originating the message
$ str r0,[r1,#12]
. str r0,[r1,#36]
8% ldr r0,[r4,#filetype]
BM teq r5,#&ff ; see if either shift was pressed
L bne no_shift
V@ cmp r0,#&2000 ; see if application
`G subeq r0,r0,#&1000 ; if so set it to directory
j
.no_shift
t str r0,[r1,#40]
~# add r0,r4,#filename
� add r2,r1,#44
�.double_clicked_loop
� ldrb r3,[r0],#1
� strb r3,[r2],#1
� teq r3,#0
�' bne double_clicked_loop
�D sub r2,r2,r1 ; r2 = length of message
� add r2,r2,#3
�8 bic r2,r2,#3 ; word align
� str r2,[r1]
�: mov r0,#18 ; reply needed
�? mov r2,#0 ; broadcast message
' swi "XWimp_SendMessage"
bvs fatal_error
ldr r0,[r1,#8]
L ldr r2,button_state ; must load this first as stored
(N ; at same address as message_myref
2$ str r0,message_myref
<J tst r2,#1 ; see if adjust double clicked
F blne remove_icon
P mov r0,#42
ZE strb r0,delete_after_drag ; tell us no drag occured
d b poll
n
xS; -----------------------------------------------------------------------------
�-; remove icon from screen and linked list
�; entry
�#; r4 -> linked list entry
�
�.remove_icon
�$ stmfd r13!,{r0-r4,r14}
�. adr r1,start_linked_list-&1000
� add r1,r1,#&1000
�.remove_icon_loop
�! ldr r2,[r1,#next]
�S teq r2,r4 ; see if found linked list entry before
�E ; the one we are deleting
� movne r1,r2
$ bne remove_icon_loop
G ldr r2,[r4,#next] ; remove the entry from the
9 str r2,[r1,#next] ; linked list
" bl delete_icon
,# bl free_heap_block
6& ldrb r2,number_of_icons
@ sub r2,r2,#1
J& strb r2,number_of_icons
T# ldmfd r13!,{r0-r4,pc}
^
hS; -----------------------------------------------------------------------------
r&; delete an icon and update screen
|; entry
�#; r4 -> linked list entry
�
�.delete_icon
� stmfd r13!,{r0-r4}
�# adr r1,delete_space
�/ ldr r0,background_window_handle
� str r0,[r1]
�( ldrb r0,[r4,#icon_handle]
� str r0,[r1,#4]
�& swi "XWimp_DeleteIcon"
� bvs fatal_error
�/ ldr r0,background_window_handle
�' ldr r1,[r4,#x_position]
' ldr r2,[r4,#y_position]
add r3,r1,#10*16
add r4,r2,#108
&' swi "XWimp_ForceRedraw"
0 bvs fatal_error
: ldmfd r13!,{r0-r4}
D movs pc,r14
N.delete_space
X equd 0
b equd 0
l
vS; -----------------------------------------------------------------------------
�; open the menu
�
�.open_menu
�& ldrb r2,number_selected
�E teq r2,#0 ; see if no icon selected
�F teqne r2,#&ff ; or icon selected by menu
�" bne icons_selected
� teq r2,#&ff
�/ bleq unselect_menu_selected_icon
�= ldr r2,[r1,#16] ; icon clicked on
�< cmn r2,#1 ; see if on icon
�9 beq icons_selected ; skip if not
� bl find_icon
mov r3,#2
F strb r3,[r4,#selected] ; mark as selected by menu
( ldrb r2,[r4,#icon_handle]
bl select_icon
* mvn r3,#0
4& strb r3,number_selected
>.icons_selected
H& ldrb r2,number_of_icons
RI teq r2,#0 ; see if no icons on backdrop
\' ldr r3,select_all_flags
fH orreq r3,r3,#1 << 22 ; set shaded bit if no icons
pH bicne r3,r3,#1 << 22 ; unset shaded bit otherwise
z' str r3,select_all_flags
�
�& ldrb r2,number_selected
�F teq r2,#0 ; see if no icons selected
�, ldr r3,clear_selection_flags
�Q orreq r3,r3,#1 << 22 ; set shaded bit if no icons selected
�H bicne r3,r3,#1 << 22 ; unset shaded bit otherwise
�, str r3,clear_selection_flags
�
�# ldr r3,remove_flags
�H orreq r3,r3,#1 << 22 ; set shaded bit if no icons
�H bicne r3,r3,#1 << 22 ; unset shaded bit otherwise
�# str r3,remove_flags
�
E ldr r2,[r1] ; r2 = mouse x coordinate
J sub r2,r2,#144 ; x coordinate to open menu at
E ldr r3,[r1,#4] ; r3 = mouse y coordinate
$J add r3,r3,#16 ; y coordinate to open menu at
. adr r1,main_menu
8& swi "XWimp_CreateMenu"
B bvs fatal_error
L b poll
V
`S; -----------------------------------------------------------------------------
j; menu data blocks
t
~.main_menu
� �string("Place It")
� equb 7
� equb 2
� equb 7
� equb 0
� equd 256
� equd 44
� equd 0
�
� equd 0
�.info_window_handle
� equd -1
( equd 1+(1 << 5)+(7 << 24)
�string("Info")
equd 0
( equd display_menu
2( equd 1+(1 << 5)+(7 << 24)
< �string("Display")
F
P equd 0
Z equd -1
d.remove_flags
n( equd 1+(1 << 5)+(7 << 24)
x �string("Remove")
�
� equd 0
� equd -1
�.select_all_flags
�( equd 1+(1 << 5)+(7 << 24)
�! �string("Select all")
�
� equd 0
� equd -1
�.clear_selection_flags
�1 equd 1+(1 << 5)+(1 << 8)+(7 << 24)
�. equd clear_selection_indirected
� equd -1
equd 16
equd 0
" equd -1
,1 equd 1+(1 << 5)+(1 << 8)+(7 << 24)
6, equd save_backdrop_indirected
@ equd -1
J equd 14
T
^< equd &80 ; last menu item
h equd -1
r( equd 1+(1 << 5)+(7 << 24)
| �string("Quit")
�.end_main_menu
�
�.display_menu
� �string("Display")
� equb 7
� equb 2
� equb 7
� equb 0
� equd 176
� equd 44
� equd 0
�
�.black_text_tick
equd 1
equd -1
( equd 1+(1 << 5)+(7 << 24)
&! �string("Black text")
0
:.white_text_tick
D< equd &80 ; last menu item
N equd -1
X( equd 1+(1 << 5)+(7 << 24)
b! �string("White text")
l
v.clear_selection_indirected
�( equs "Clear selection"+�0
�.save_backdrop_indirected
�& equs "Save backdrop"+�0
� align
�
�S; -----------------------------------------------------------------------------
�"; Our drag operation has ended
�
�
.drag_end
�% adr r1,workspace+&400
� sub r1,r1,#&400
�* swi "XWimp_GetPointerInfo"
� bvs fatal_error
ldr r0,[r1,#12]
/ ldr r3,background_window_handle
L teq r0,r3 ; see if dragged onto our window
! bne get_task_name
*I ldmia r1,{r0,r2} ; get coords where drag ended
4G str r3,[r1] ; store window handle at r1
># ldr r3,drag_x_start
H# ldr r4,drag_y_start
R sub r3,r0,r3
\ sub r4,r2,r4
f. adr r5,start_linked_list-&1000
p add r5,r5,#&1000
z ldr r5,[r5]
�.drag_end_loop
�% ldrb r0,[r5,#selected]
� teq r0,#0
�& beq drag_end_loop_skip
�( ldrb r0,[r5,#icon_handle]
� str r0,[r1,#4]
�& swi "XWimp_DeleteIcon"
� bvs fatal_error
�' ldr r0,[r5,#x_position]
� add r0,r0,r3
�' str r0,[r5,#x_position]
� str r0,[r1,#4]
� add r0,r0,#10*16
str r0,[r1,#12]
' ldr r0,[r5,#y_position]
add r0,r0,r4
$' str r0,[r5,#y_position]
. str r0,[r1,#8]
8 add r0,r0,#108
B str r0,[r1,#16]
L! ldr r0,icon_flags
V str r0,[r1,#20]
`/ ldr r0,[r5,#offset_to_leafname]
j add r0,r0,r5
t str r0,[r1,#24]
~& add r0,r5,#sprite_name
� str r0,[r1,#28]
� mov r0,#12
� str r0,[r1,#32]
�& swi "XWimp_CreateIcon"
� bvs fatal_error
�( strb r0,[r5,#icon_handle]
�.drag_end_loop_skip
�! ldr r5,[r5,#next]
� teq r5,#0
�! bne drag_end_loop
�P adr r0,drag_x_min ; get initial coordinates of
�A ldmia r0,{r1-r4} ; box dragged
/ ldr r0,background_window_handle
' swi "XWimp_ForceRedraw"
bvs fatal_error
bl unselect_all
( b poll
2.get_task_name
<& adr r1,poll_space+&800
F sub r1,r1,#&800
P* swi "XWimp_GetPointerInfo"
Z bvs fatal_error
d ldr r2,[r1,#12]
nC str r2,datasave_window_handle ; store window handle
x ldr r3,[r1,#16]
�? str r3,datasave_icon_handle ; store icon handle
� ldr r0,[r1,#0]
�; str r0,datasave_mouse_x ; store mouse x
� ldr r0,[r1,#4]
�; str r0,datasave_mouse_y ; store mouse y
�
�% adr r1,workspace+&400
�E mov r0,#24 ; length of message block
�# str r0,[r1,#-&400]!
� mov r0,#0
�> str r0,[r1,#12] ; original message
� mov r0,#&40000
�@ add r0,r0,#&c6 ; message_tasknamerq
str r0,[r1,#16]
O mov r0,#19 ; use to find task handle of window
> ; r2,3 already set
"S swi "XWimp_SendMessage" ; no message will be sent but r2 = task
,> bvs fatal_error ; handle of window
6 str r2,[r1,#20]
@= mov r0,#17 ; no reply wanted
J? mov r2,#0 ; broadcast message
T' swi "XWimp_SendMessage"
^ bvs fatal_error
h ldr r0,[r1,#8]
r$ str r0,message_myref
| b poll
�
�.tasknameis
�' ldr r0,start_filer_name
� ldr r2,[r1,#28]
�= teq r0,r2 ; see if the same
�) bne send_dataload_message
� ldrb r0,[r1,#32]
� teq r0,#�"r"
�) bne send_dataload_message
� ldrb r0,[r1,#33]
� teq r0,#0
�) bne send_dataload_message
� mov r0,#1
E strb r0,save_to_filer ; set flag (message type)
- b send_datasaveload_message
.start_filer_name
& equs "File"
0.send_dataload_message
: mov r0,#3
DE strb r0,save_to_filer ; set flag (message type)
N.send_datasaveload_message
X. adr r4,start_linked_list-&1000
b add r4,r4,#&1000
l ldr r4,[r4]
v#.send_datasaveload_message_loop
�& adr r1,poll_space+&800
� sub r1,r1,#&800
�% ldrb r0,[r4,#selected]
�= teq r0,#0 ; see if selected
�: beq send_datasaveload_message_not_selected
�! bl unselect_icon
�& ldrb r0,number_selected
� sub r0,r0,#1
�& strb r0,number_selected
�% ldr r0,[r4,#filetype]
� str r0,[r1,#40]
�J mov r0,#17 ; read catalogue info, no path
�# add r1,r4,#filename
9 mov r6,r4 ; preserve r4
swi "XOS_File"
8 movvs r4,r6 ; restore r4
> adrvs r14,send_datasaveload_message_not_selected
*# bvs report_error_ok
4 teq r0,#0
>2 bne send_datasaveload_message_skip
H8 mov r4,r6 ; restore r4
R< mov r0,#19 ; generate error
\ swi "XOS_File"
f# bl report_error_ok
p: b send_datasaveload_message_not_selected
z#.send_datasaveload_message_skip
�& adr r1,poll_space+&800
�6 sub r1,r1,#&800 ; reset r1
�B str r4,[r1,#36] ; store length of file
�8 mov r4,r6 ; restore r4
�$ ldrb r5,save_to_filer
�D teq r5,#1 ; see if saving to filer
�/ ldreq r2,[r4,#offset_to_leafname]
�@ addeq r2,r2,r4 ; if so use leafname
�B addne r2,r4,#filename ; not so use full name
� add r3,r1,#44
�$.send_datasaveload_message_loop2
� ldrb r5,[r2],#1
� strb r5,[r3],#1
teq r5,#0
3 bne send_datasaveload_message_loop2
A sub r3,r3,r1 ; r3 = message length
$ add r3,r3,#3
.G bic r3,r3,#3 ; round up to word boundary
8 str r3,[r1]
BL mov r0,#0 ; we are originating the message
L str r0,[r1,#12]
V$ ldrb r0,save_to_filer
`> str r0,[r1,#16] ; set message type
j' ldr r0,datasave_mouse_x
t str r0,[r1,#28]
~' ldr r0,datasave_mouse_y
� str r0,[r1,#32]
�: mov r0,#18 ; reply needed
�N ldr r2,datasave_window_handle ; r2 = destination window handle
� str r2,[r1,#20]
�L ldr r3,datasave_icon_handle ; r3 = destination window handle
�? ; incase on iconbar
� str r3,[r1,#24]
�' swi "XWimp_SendMessage"
� bvs fatal_error
� ldr r0,[r1,#8]
�$ str r0,message_myref
�+ str r4,datasave_where_up_to
K b poll ; poll to receive message reply
'.send_datasaveload_message_continue
+ ldr r4,datasave_where_up_to
+.send_datasaveload_message_not_selected
(& adr r1,poll_space+&800
2 sub r1,r1,#&800
< ldr r4,[r4]
F(.send_datasaveload_message_continue2
P teq r4,#0
Z2 bne send_datasaveload_message_loop
d b poll
n
x.datasave_where_up_to
� equd 0
�.datasave_window_handle
� equd 0
�.datasave_icon_handle
� equd 0
�.datasave_mouse_x
� equd 0
�.datasave_mouse_y
� equd 0
�
�S; -----------------------------------------------------------------------------
�&; The user has clicked on our meny
�
.menu_select
# adr r1,pointer_info
* swi "XWimp_GetPointerInfo"
" bvs fatal_error
,& adr r1,poll_space+&800
6 sub r1,r1,#&800
@C ldr r0,[r1] ; r0 = first menu entry
JB cmn r0,#1 ; see if on menu entry
TP addne pc,pc,r0,lsl #2 ; was so dispatch to correct routine
^G b poll ; not on menu entry so poll
h.jump_table
r2 b poll ; info
|= b menu_display ; display submenu
�4 b remove ; remove
�8 b select_all ; select_all
�= b clear_selection ; clear_selection
�; b save_backdrop ; save_backdrop
�2 b closedown_and_exit ; quit
�
�S; -----------------------------------------------------------------------------
�4; an entry on the display menu has been selected
�
�.menu_display
� ldr r0,[r1,#4]
�@ cmp r0,#0 ; sort where clicked
�O blt poll ; not menu item on click on display
H ; in main menu so poll again
moveq r0,#1
movgt r0,#0
&& str r0,black_text_tick
0
:' strb r0,icon_text_colour
D
N moveq r0,#&80
X movne r0,#&81
b& str r0,white_text_tick
l
v! ldr r0,icon_flags
�" bic r0,r0,#7 << 24
�" eoreq r0,r0,#7 << 24
�! str r0,icon_flags
�
�% adr r1,workspace+&800
�/ ldr r0,background_window_handle
�# str r0,[r1,#-&800]!
� moveq r0,#7 << 24
� movne r0,#0
� str r0,[r1,#8]
� mov r0,#15 << 24
� str r0,[r1,#12]
�( ldr r4,start_linked_list
!D teq r4,#0 ; see if no icons at all
!& beq see_if_reopen_menu
!.menu_display_loop
! ( ldrb r0,[r4,#icon_handle]
!* str r0,[r1,#4]
!4( swi "XWimp_SetIconState"
!> bvs fatal_error
!H! ldr r4,[r4,#next]
!R teq r4,#0
!\% bne menu_display_loop
!f& b see_if_reopen_menu
!p
!zS; -----------------------------------------------------------------------------
!�.; the remove menu option has been selected
!�
!�.remove
!�- adr r5,start_linked_list-&c00
!�" ldr r4,[r5,#&c00]!
!�.remove_loop
!�R ldr r6,[r4,#next] ; must be read here as freeing a block
!�L ; changes the value of [r4+next]
!�% ldrb r2,[r4,#selected]
!� teq r2,#0
!�O streq r4,[r5,#next] ; store linked list pointer in last
!�R ; not removed data set if not removing
!�N moveq r5,r4 ; update last not removed data set
"E ; pointer if not removing
" beq not_remove
" bl delete_icon
"$# bl free_heap_block
".& ldrb r2,number_of_icons
"8 sub r2,r2,#1
"B& strb r2,number_of_icons
"L.not_remove
"V= movs r4,r6 ; move along list
"`; teq r4,#0 ; see if at end
"j bne remove_loop
"tE str r4,[r5,#next] ; mark end of linked list
"~& strb r4,number_selected
"�& b see_if_reopen_menu
"�
"�S; -----------------------------------------------------------------------------
"�2; the select all menu option has been selected
"�
"�.select_all
"�( ldr r4,start_linked_list
"�.select_all_loop
"�( ldrb r2,[r4,#icon_handle]
"� bl select_icon
"� mov r2,#1
"�% strb r2,[r4,#selected]
# ldr r4,[r4]
#
teq r4,#0
## bne select_all_loop
#& ldrb r2,number_of_icons
#(& strb r2,number_selected
#2& b see_if_reopen_menu
#<
#FS; -----------------------------------------------------------------------------
#P6; the clear selecton menu option has been selected
#Z
#d.clear_selection
#n bl unselect_all
#x& b see_if_reopen_menu
#�
#�S; -----------------------------------------------------------------------------
#�5; the save backdrop menu entry has been selected.
#�
#�.save_backdrop
#� mov r0,#&80
#�& adr r1,config_filename
#� swi "XOS_Find"
#�! adrvs r14,poll+&800
#�M subvs r14,r14,#&800 ; cause it to return to poll loop
#�# bvs report_error_ok
#�> mov r1,r0 ; r1 = file handle
#�D ldrb r0,icon_text_colour ; store icon text colour
$ swi "XOS_BPut"
$' bvs error_while_writing
$C ldrb r0,number_of_icons ; store number of icons
$" swi "XOS_BPut"
$,' bvs error_while_writing
$6( ldr r2,start_linked_list
$@ teq r2,#0
$J beq end_of_save
$T.save_backdrop_loop
$^S mov r0,#2 ; write bytes using current seq pointer
$h> ; r1 = file handle
$rG ldr r5,[r2,#next] ; get pointer to next entry
$|" ldr r3,[r2,#size]!
$� sub r3,r3,#4
$� swi "XOS_GBPB"
$�' bvs error_while_writing
$�I movs r2,r5 ; r2 -> next entry, set flags
$� teq r2,#0
$�& bne save_backdrop_loop
$�.end_of_save
$�S mov r0,#2 ; write bytes using current seq pointer
$�= adr r2,zero ; r2 -> &00000000
$� mov r3,#4
$� swi "XOS_GBPB"
$�' bvs error_while_writing
$�8 mov r0,#0 ; close file
% swi "XOS_Find"
%# blvs report_error_ok
%& b see_if_reopen_menu
%&.error_while_writing
%0A mov r2,r0 ; store error pointer
%:8 mov r0,#0 ; close file
%D? swi "XOS_Find" ; ignore any errors
%NC mov r0,r2 ; restore error pointer
%X# bl report_error_ok
%b b poll
%l .zero
%v equd 0
%�.config_filename
%�. equs "<PlaceIt$Dir>.!Config"+�0
%� align
%�
%�S; -----------------------------------------------------------------------------
%�5; see if adjust was clicked on. if so reopen menu
%�
%�.see_if_reopen_menu
%�? ldr r0,pointer_info+8 ; r0 = button state
%�C tst r0,#1 ; see if adjust pressed
%�< beq poll ; wasn't so poll
%�E adr r1,pointer_info ; r1 -> click coordinates
%� mvn r0,#0
&D str r0,[r1,#16] ; no icon was clicked on
&9 b open_menu ; reopen menu
&
& .pointer_info
&* equs �24,�0)
&4
&>S; -----------------------------------------------------------------------------
&H); The nice wimp has sent us a message
&R
&\.message
&f8 ldr r11,[r1,#16] ; message ID
&p> teq r11,#0 ; see if closedown
&z& beq closedown_and_exit
&� mov r0,#&c1
&�! add r0,r0,#&40000
&�H teq r11,r0 ; see if mode change message
&�G bleq read_screen_size ; this call preserves flags
&� beq poll
&�? add r0,r0,#6 ; see if tasknameis
&� teq r11,r0
&� beq tasknameis
&�@ teq r11,#2 ; see if datasaveack
&� beq datasaveack
&�@ teq r11,#4 ; see if dataloadack
&� beq dataloadack
&�= teq r11,#3 ; see if dataload
' bne poll
'
'S; -----------------------------------------------------------------------------
'$B; we have received a dataload message. see if we can handle it
'.
'8
.dataload
'B; ldr r0,[r1,#12] ; r0 = your_ref
'LA cmp r0,#0 ; check sent by filer
'V9 bne poll ; poll if not
'`J ldr r3,[r1] ; r3 = length of message block
'jK sub r3,r3,#44-filename ; r3 = amount of storage needed
't" bl get_heap_block
'~ teq r2,#0
'�( beq no_more_memory_error
'�! str r3,[r2,#size]
'�- adr r4,start_linked_list-&c00
'� add r4,r4,#&c00
'�.dataload_loop1
'�! ldr r5,[r4,#next]
'� teq r5,#0
'� movne r4,r5
'�" bne dataload_loop1
'�L str r2,[r4,#next] ; store pointer to next data set
'�P str r5,[r2,#next] ; r5 = 0, mark next data set as last
'� mov r4,r2
( P ldr r0,[r1,#40] ; r0 = filetype of file to be loaded
(
% str r0,[r4,#filetype]
(I add r0,r1,#44 ; r0 -> filename to be loaded
(# add r2,r4,#filename
(( sub r5,r2,r4
(2.dataload_loop2
(< ldrb r3,[r0],#1
(F strb r3,[r2],#1
(P teq r3,#�"."
(ZE subeq r5,r2,r4 ; r5 = offset to leafname
(d teq r3,#0
(n" bne dataload_loop2
(x/ str r5,[r4,#offset_to_leafname]
(�S add r5,r5,r4 ; r5 -> leafname, to use as sprite text
(� mov r2,r1
(�% adr r1,workspace+&c00
(� sub r1,r1,#&c00
(�/ ldr r0,background_window_handle
(� str r0,[r1]
(�P ldr r0,[r2,#28] ; r0 = x coordinate where drag ended
(� sub r0,r0,#5*16
(�; str r0,[r1,#4] ; min x of icon
(�' str r0,[r4,#x_position]
(� add r0,r0,#10*16
(�; str r0,[r1,#12] ; max x of icon
(�P ldr r0,[r2,#32] ; r0 = y coordinate where drag ended
) sub r0,r0,#54
); str r0,[r1,#8] ; min y of icon
)' str r0,[r4,#y_position]
)" add r0,r0,#108
),; str r0,[r1,#16] ; max y of icon
)6! ldr r0,icon_flags
)@ str r0,[r1,#20]
)JJ str r5,[r1,#24] ; store pointer to sprite text
)T& add r0,r4,#sprite_name
)^P str r0,[r1,#28] ; store pointer to validation string
)h mov r2,#11
)r str r2,[r1,#32]
)| mov r2,#�"S"
)� strb r2,[r0],#1
)�% ldr r3,[r4,#filetype]
)�D cmp r3,#&1000 ; see if has no filetype
)� bge no_filetype
)� mov r2,#�"f"
)� strb r2,[r0],#1
)� mov r2,#�"i"
)� strb r2,[r0],#1
)� mov r2,#�"l"
)� strb r2,[r0],#1
)� mov r2,#�"e"
)� strb r2,[r0],#1
)�S mov r1,r0 ; r1 = buffer to store converted number
*; mov r0,r3 ; r0 = filetype
*< mov r2,#5 ; size of buffer
*% swi "XOS_ConvertHex4"
*& bvs fatal_error
*0 mov r2,#�"_"
*: strb r2,[r0]
*D? sub r2,r0,#4 ; r2 -> sprite name
*N( bl see_if_sprite_exists
*XL movvs r0,r2 ; r0 -> where to put sprite name
*bH adrvs r2,file_xxx ; sprite wasn't found so use
*l> bvs no_filetype_loop ; file_xxx instead
*v# b finish_dataload
*�.application
*�/ ldr r2,[r4,#offset_to_leafname]
*� add r2,r2,r4
*�( bl see_if_sprite_exists
*�N adrvs r2,application_sprite ; use "application" as sprite name
*�J ; as sprite could not be found
*�$ b no_filetype_loop
*�
*�.application_sprite
*�$ equs "application"+�0
*�.directory
*�" equs "directory"+�0
*�
.file_xxx
+! equs "file_xxx"+�0
+ align
+
+ .no_filetype
+* cmp r3,#&2000
+4 adrlt r2,directory
+> beq application
+H adrgt r2,file_xxx
+R.no_filetype_loop
+\ ldrb r3,[r2],#1
+f strb r3,[r0],#1
+p teq r3,#0
+z$ bne no_filetype_loop
+�
+�.finish_dataload
+�% adr r1,workspace+&c00
+� sub r1,r1,#&c00
+�& swi "XWimp_CreateIcon"
+� bvs fatal_error
+�( strb r0,[r4,#icon_handle]
+� mov r0,#0
+�% strb r0,[r4,#selected]
+�@ ldr r0,[r1] ; r0 = window handle
+�8 ldr r2,[r1,#8] ; r2 = min y
+�8 ldr r3,[r1,#12] ; r3 = max x
+�8 ldr r4,[r1,#16] ; r4 = max y
,8 ldr r1,[r1,#4] ; r1 = min x
,' swi "XWimp_ForceRedraw"
, bvs fatal_error
,$& ldrb r0,number_of_icons
,. add r0,r0,#1
,8& strb r0,number_of_icons
,B& adr r1,poll_space+&c00
,L sub r1,r1,#&c00
,V ldr r0,[r1,#12]
,` strb r0,[r1,#8]
,j= ldr r2,[r1,#4] ; reply to sender
,t= mov r0,#17 ; no reply needed
,~' swi "XWimp_SendMessage"
,� bvs fatal_error
,� b poll
,�
,�.no_more_memory_error
,�1 adr r0,no_more_memory_error_block
,�# bl report_error_ok
,� b poll
,�.no_more_memory_error_block
,� equd 0
,�/ equs "Not enough free memory"+�0
,� align
,�.icon_flags
- X equd 1+(1 << 1)+(1 << 3)+(1 << 5)+(1 << 8)+(10 << 12)+(7 << 24)+(4 << 28)
-
-S; -----------------------------------------------------------------------------
-,; we have received a datasaveack message
-(
-2.datasaveack
-< ldr r0,[r1,#12]
-F$ ldr r2,message_myref
-PD teq r0,r2 ; check we originated it
-Z bne poll
-dM swi "XHourglass_On" ; don't report errors as may have
-n< ; been unplugged
-x2 mov r0,#26 ; copy
-�H add r2,r1,#44 ; r2 -> destination filename
-�+ ldr r1,datasave_where_up_to
-�C add r1,r1,#filename ; r1 -> source filename
-�< mov r3,#1 ; flags for copy
-�# swi "XOS_FSControl"
-� bvc copy_ok
-�M swi "XHourglass_Off" ; don't report errors as may have
-�< ; been unplugged
-�# bl report_error_ok
-�6 b send_datasaveload_message_continue
-�.copy_ok
-�M swi "XHourglass_Off" ; don't report errors as may have
-�< ; been unplugged
.& adr r1,poll_space+&c00
. sub r1,r1,#&c00
. ldr r0,[r1,#12]
." str r0,[r1,#8]
.,> mov r0,#3 ; dataload message
.6 str r0,[r1,#16]
.@: mov r0,#18 ; reply needed
.J= ldr r2,[r1,#4] ; reply to sender
.T' swi "XWimp_SendMessage"
.^ bvs fatal_error
.h ldr r0,[r1,#8]
.r$ str r0,message_myref
.|K b poll ; poll so that we receive reply
.�
.�S; -----------------------------------------------------------------------------
.�,; we have received a dataloadack message
.�
.�.dataloadack
.� ldr r0,[r1,#12]
.�$ ldr r2,message_myref
.�D teq r0,r2 ; check we originated it
.� bne poll
.�( ldrb r0,delete_after_drag
.�Q teq r0,#42 ; see if response to dataopen message
.�= beq poll ; if so just poll
.�H teq r0,#&ff ; see whether to delete icon
/+ ldreq r4,datasave_where_up_to
/R ldr r0,[r4,#next] ; this will be changed by freeing heap
/3 ; block
/& bleq remove_icon
/0 mov r4,r0
/:& adr r1,poll_space+&c00
/D sub r1,r1,#&c00
/N7 b send_datasaveload_message_continue2
/X
/bS; -----------------------------------------------------------------------------
/l4; see if a sprite exists in the wimp_sprite pool
/v; entry
/�; r2 -> sprite name
/�
; exit
/�#; v unset => sprite found
/�'; set => sprite not found
/�
/�.see_if_sprite_exists
/�# stmfd r13!,{r0,r3-r6}
/�> mov r0,#40 ; read sprite info
/�$ swi "XWimp_SpriteOp"
/�# ldmfd r13!,{r0,r3-r6}
/� mov pc,r14
/�
/�S; -----------------------------------------------------------------------------
09; The nice wimp has sent us a message acknowledgement
0
0.message_acknowledged
0 ldr r0,[r1,#8]
0*$ ldr r2,message_myref
04D cmp r0,r2 ; see if one our message
0>O bne poll ; poll otherwise, can this happen ?
0H ldr r0,[r1,#16]
0RE teq r0,#1 ; see if datasave message
0\- beq datasave_not_acknowledged
0fE teq r0,#3 ; see if dataload message
0p- beq dataload_not_acknowledged
0zE teq r0,#5 ; see if dataopen message
0�9 bne poll ; if not poll
0�: ldr r0,[r1,#40] ; get filetype
0�> cmp r0,#&1000 ; see if directory
0�, adreq r2,filer_opendir_command
0�" adrne r2,run_command
0�H add r0,r1,#30 ; r0 -> where to put command
0�.message_ack_loop
0� ldrb r3,[r2],#1
0� teq r3,#0
0� strneb r3,[r0],#1
0�$ bne message_ack_loop
0�; add r0,r1,#30 ; r0 -> command
0�% swi "XWimp_StartTask"
1 bvs fatal_error
1 b poll
1.filer_opendir_command
1$' equs "Filer_OpenDir "+�0
1..run_command
18' equs "Run "+�0
1B align
1L
1V.datasave_not_acknowledged
1`6 beq send_datasaveload_message_continue
1j
1t.dataload_not_acknowledged
1~6 b send_datasaveload_message_continue
1�
1�S; -----------------------------------------------------------------------------
1�; heap handling routines
1�
1�S; -----------------------------------------------------------------------------
1�9; get a heap block. If fails try and extend wimp_slot
1�; entry
1�; r3 = size wanted
1�
; exit
1�); r2 -> heap block if succeeded
1�7; r2 = 0 if failed, r3 corrupted in this case
1�
2 .get_heap_block
2
* stmfd r13!,{r0-r1,r4-r6,r14}
2 mov r6,r3
2< mov r0,#2 ; get heap block
2(& adr r1,heap_start-&800
22 add r1,r1,#&800
2< swi "XOS_Heap"
2FA ldmvcfd r13!,{r0-r1,r4-r6,pc} ; if succeeded return
2P mvn r0,#0
2Z mov r1,r0
2d$ swi "XWimp_SlotSize"
2n bvs fatal_error
2x< mov r5,r0 ; store old size
2�F add r0,r0,#8*1024 ; we want some more memory
2� mvn r1,#0
2�$ swi "XWimp_SlotSize"
2�> movvs r2,#0 ; r2 = 0 if failed
2�9 ldmvsfd r13!,{r0-r1,r4-r6,pc} ; then return
2�N sub r3,r0,r5 ; r3 = amount of new memory we got
2�& adr r1,heap_start-&800
2� add r1,r1,#&800
2�9 mov r0,#5 ; extend heap
2� swi "XOS_Heap"
2� bvs fatal_error
2�< mov r0,#2 ; get heap block
2� mov r3,r6
3 swi "XOS_Heap"
3I bvs fatal_error ; we should succeed this time
3) ldmfd r13!,{r0-r1,r4-r6,pc}
3"
3,S; -----------------------------------------------------------------------------
36; free a heap block
3@; entry
3J; r4 -> heap block
3T
3^.free_heap_block
3h stmfd r13!,{r0-r2}
3r= mov r0,#3 ; free heap block
3|& adr r1,heap_start-&400
3� add r1,r1,#&400
3� mov r2,r4
3� swi "XOS_Heap"
3� bvs fatal_error
3� ldmfd r13!,{r0-r2}
3� mov pc,r14
3�
3�S; -----------------------------------------------------------------------------
3�(; search the linked list for an icon
3�; entry
3�; r2 = icon handle
3�
; exit
3�+; r4 -> data entry in linked list
4
4.find_icon
4 stmfd r13!,{r3}
4&( ldr r4,start_linked_list
40.find_icon_loop
4:( ldrb r3,[r4,#icon_handle]
4D teq r3,r2
4N ldmeqfd r13!,{r3}
4X moveq pc,r14
4b! ldr r4,[r4,#next]
4l" b find_icon_loop
4v
4�S; -----------------------------------------------------------------------------
4�&; select an icon on the background
4�; entry
4�; r2 = icon handle
4�
4�.select_icon
4� stmfd r13!,{r1,r3}
4�& adr r1,workspace+&1000
4� sub r1,r1,#&1000
4�/ ldr r3,background_window_handle
4� str r3,[r1]
4� str r2,[r1,#4]
4� mov r3,#1 << 21
5 str r3,[r1,#8]
5 str r3,[r1,#12]
5( swi "XWimp_SetIconState"
5 bvs fatal_error
5* ldmfd r13!,{r1,r3}
54 movs pc,r14
5>
5HS; -----------------------------------------------------------------------------
5R*; unselect the sprite selected by menu
5\
5f .unselect_menu_selected_icon
5p$ stmfd r13!,{r3-r4,r14}
5z( ldr r4,start_linked_list
5�%.unselect_menu_selected_icon_loop
5�% ldrb r3,[r4,#selected]
5�B teq r3,#2 ; see if menu selected
5�! ldrne r4,[r4,#next]
5�4 bne unselect_menu_selected_icon_loop
5�! bl unselect_icon
5� mov r3,#0
5�& strb r3,number_selected
5�# ldmfd r13!,{r3-r4,pc}
5�
5�S; -----------------------------------------------------------------------------
5�H; unselect an icon on the background. and unsets flags in data entry
5�; entry
6; r4 -> data_entry
6
6.unselect_icon
6$ stmfd r13!,{r1,r3}
6.% ldrb r3,[r4,#selected]
68= teq r3,#1 ; see if selected
6BB ldmnefd r13!,{r1,r3} ; not so restore r1,r3
6L9 movnes pc,r14 ; then return
6V& adr r1,workspace+&1000
6` sub r1,r1,#&1000
6j/ ldr r3,background_window_handle
6t str r3,[r1]
6~( ldrb r3,[r4,#icon_handle]
6� str r3,[r1,#4]
6� mov r3,#0
6� str r3,[r1,#8]
6� mov r3,#1 << 21
6� str r3,[r1,#12]
6�( swi "XWimp_SetIconState"
6� bvs fatal_error
6� mov r3,#0
6�A strb r3,[r4,#selected] ; store as unselected
6� ldmfd r13!,{r1,r3}
6� movs pc,r14
6�
7 S; -----------------------------------------------------------------------------
7
A; unselect all icons and set number of selected icons to zero
7
7.unselect_all
7($ stmfd r13!,{r2,r4,r14}
72( ldr r4,start_linked_list
7<C teq r4,#0 ; see if no icons exist
7F: ldmeqfd r13!,{r2,r4,pc} ; if so return
7P.clear_selection_loop
7Z! bl unselect_icon
7d ldr r4,[r4]
7n teq r4,#0
7x( bne clear_selection_loop
7�& strb r4,number_selected
7�$ ldmfd r13!,{r2,r4,pc}^
7�
7�S; -----------------------------------------------------------------------------
7�@; This routine reads the screen size in external coordinates
7�
7�.read_screen_size
7� stmfd r13!,{r14}
7�E mvn r0,#0 ; read about current mode
7�= mov r1,#4 ; r1 = XEigFactor
7�* swi "XOS_ReadModeVariable"
7� bvs fatal_error
7� mov r3,r2
8= mov r1,#11 ; r1 = XWindLimit
8* swi "XOS_ReadModeVariable"
8 bvs fatal_error
8" mov r2,r2,lsl r3
8," str r2,screen_maxx
86$ str r2,workarea_maxx
8@= mov r1,#5 ; r1 = YEigFactor
8J* swi "XOS_ReadModeVariable"
8T bvs fatal_error
8^ mov r3,r2
8h= mov r1,#12 ; r1 = YWindLimit
8r* swi "XOS_ReadModeVariable"
8| bvs fatal_error
8� mov r2,r2,lsl r3
8�" str r2,screen_maxy
8�$ str r2,workarea_maxy
8� str r2,scroll_y
8� mov r0,#1
8�# strb r0,mode_changed
8�< ldmfd r13!,{pc}^ ; preserve flags
8�
8�S; -----------------------------------------------------------------------------
8�; closedown and exit
8�
8�.closedown_and_exit
8� bl closedown
9 swi "OS_Exit"
9
9S; -----------------------------------------------------------------------------
9&M; either we could not start up, the user wants us to closedown or we have
90$; had a module finalisation call
9:
9D.closedown
9N( adr r1,task_handle+&1000
9X sub r1,r1,#&1000
9b ldr r0,[r1]
9l- ldr r1,[r1,#task-task_handle]
9v> swi "XWimp_CloseDown" ; close down if so
9� mov pc,r14
9�
9�S; -----------------------------------------------------------------------------
9�; misc flags and data
9�
9�.mode_changed
9� equb 0
9�.icon_text_colour
9� equb 1
9�.delete_after_drag
9� equb 0
9�.number_of_icons
9� equb 0
:.number_selected
: equb 0
:.save_to_filer
: equb 0
:* align
:4.button_state
:>.heap_entry_length
:H.message_myref
:R equd 0
:\
:fS; -----------------------------------------------------------------------------
:p;; define the background window. v set if error occurred
:z
:�.define_background_window
:� stmfd r13!,{r14}
:�$ bl read_screen_size
:�( adr r1,background_window
:�( swi "XWimp_CreateWindow"
:� ldmvsfd r13!,{pc}
:�/ adr r1,background_window_handle
:� str r0,[r1]
:�& swi "XWimp_OpenWindow"
:� ldmfd r13!,{pc}
:�
:�S; -----------------------------------------------------------------------------
:�"; background window data block
;
;.background_window_handle
; equd 0
;$.background_window
;. equd 0
;8 equd 136
;B.screen_maxx
;L equd 0
;V.screen_maxy
;` equd 0
;j equd 0
;t
.scroll_y
;~ equd 0
;�< equd -2 ; open at bottom
;�0 equd (1 << 4)+(1 << 11)+(1 << 31)
;� equb &ff
;� equb 0
;� equb 7
;�F equb 4 ; window background colour
;� equb 0
;� equb 0
;� equb 0
;� equb 0
;�.workarea_coords
;� equd 0
<