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 <