home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / a / appsswi / ZSource / ErrorSrc (.txt) < prev    next >
Encoding:
RISC OS BBC BASIC V Source  |  1995-04-23  |  39.2 KB  |  1,226 lines

  1.  ErrorWindow 0.04 - give nice error windows, on RISC OS 3.1 and above
  2.  by AjC of DoggySoft
  3.  Requires BAX 1.00 or later to compile. Source best viewed in a big mode, 114 column formatting
  4. trappedswi=&400DF-&400C0
  5. scratchsize=256
  6. minimumbuttonwidth=166
  7. numberofbuttons=6
  8. buttonthatdeletessprites=5
  9. twospriteseparation=8
  10. buttondelay=15
  11. wimpinitver=200
  12. icon_colourbox=0
  13. icon_innerframe=2
  14. icon_message=3
  15. icon_title=4
  16. icon_titlejoin=6
  17. icon_typeicon=7
  18. icon_application=8
  19. icon_firstbutton=9
  20. OS_WriteI=256
  21. Wimp_TextOp=&400F9
  22. XOS_WriteI=&20000+OS_WriteI
  23. #XWimp_TextOp=&20000+Wimp_TextOp
  24. service_reporterror=&57
  25.  service_errorstarting=&400C0
  26. %service_errorbuttonpressed=&400C1
  27. service_errorending=&400C2
  28. os_byte_flush=21
  29. os_byte_ptrshape=106
  30. os_byte_scankeys=121
  31. $!os_byte_acknowledgeescape=126
  32. os_byte_readkeys=129
  33. os_byte_readcmos=161
  34. os_word_mouse=21
  35. os_word_mouse_bbox=1
  36. os_module_quit=4
  37. os_module_claim=6
  38. os_module_release=7
  39. os_file_load=16
  40. os_file_info=17
  41. os_spriteop_select=24
  42. os_spriteop_setpointer=36
  43. 0 os_spriteop_switchcontext=60
  44. wimp_readsysinfo_task=5
  45. wimp_readsysinfo_wimpver=7
  46. wimp_textop_stringwidth=1
  47. buffer_keyboard=0
  48. buffer_mouse=9
  49. cmos_wimpflags=197
  50. iconflag_selected=21
  51. iconflag_deleted=23
  52. modevar_xpix=11
  53. modevar_ypix=12
  54. modevar_xeig=4
  55. modevar_yeig=5
  56. fbit=26
  57. ibit=27
  58. vbit=28
  59. cbit=29
  60. zbit=30
  61. nbit=31
  62. colour_blue=8
  63. colour_red=11
  64. colour_green=13
  65. w=0 :wk_messagesblock=w
  66. w+=4:wk_windowblock=w
  67. w+=4:wk_indirblock=w
  68. w+=4:wk_scratchblock=w
  69. w+=4:wk_windowhandle=w
  70. w+=4:wk_threaded=w
  71. w+=4:wk_numberofbuttons=w
  72. w+=4:wk_buttonwidth=w
  73. w+=4:wk_firstuserbutton=w
  74. w+=4:wk_describebutton=w
  75. w+=4:wk_oldptrshape=w
  76. w+=4:wk_temptaskhandle=w
  77. V!w+=4:wk_baderrorcanceladded=w
  78.  code 100000
  79.  0,"Error in compilation, pass "+
  80. pass+": "+
  81. $+", at line "+
  82.  pass=4
  83. O%=code:P%=0
  84. [OPT pass
  85.   Equd    0
  86.   Equd    mod_init
  87.   Equd    mod_quit
  88.   Equd    mod_service
  89.   Equd    mod_title
  90.   Equd    mod_help
  91.   Equd    0
  92.   Equd    0
  93.   Equd    0
  94.   Equd    0
  95.   Equd    0
  96. .serv_errorstarting
  97. m#  Equd    service_errorstarting
  98. .serv_errorbuttonpressed
  99. p(  Equd    service_errorbuttonpressed
  100. .serv_errorending
  101. s!  Equd    service_errorending
  102. .specialfilter
  103.   Equs    "WSWI"
  104. .wimptask
  105.   Equs    "TASK"
  106. .mod_title
  107.   Equz    "3DErrorWindow"
  108.   Align
  109. .mod_help
  110. "  Equs    "3D Error Window"+
  111. "  Equz    "0.04 (27 Apr 1995)"
  112. .messagesfile
  113. &  Equz    "3DErrorWindow:Messages"
  114. .templatesfile
  115. '  Equz    "3DErrorWindow:Templates"
  116. .templatename
  117.   Equz    "Error"
  118. .t_oldtitleprefix
  119.   Equs    "TitleO="
  120. .t_newtitleprefix0
  121.   Equs    "Title0="
  122. .t_newtitleprefix1
  123.   Equs    "Title1="
  124. .t_newtitleprefix2
  125.   Equs    "Title2="
  126. .t_newtitleprefix3
  127.   Equs    "Title3="
  128. .t_newtitleprefix4
  129.   Equs    "Title4="
  130. .t_newtitleprefix5
  131.   Equs    "Title5="
  132. .t_titlefrom
  133.   Equs    "TitleFrom="
  134. .t_oldok
  135.   Equs    "OldOK="
  136. .t_newok
  137.   Equs    "NewOK="
  138. .t_cancel
  139.   Equs    "Cancel="
  140. .t_quit
  141.   Equs    "Quit="
  142. .t_describe
  143.   Equs    "Describe="
  144. .t_baderror
  145.   Equs    "BadError="
  146. .t_unknowntask
  147.   Equs    "UnknownTask="
  148. .spritetype0
  149.   Equz    "error"
  150. .spritetype1
  151.   Equz    "information"
  152. .spritetype2
  153.   Equz    "warning"
  154. .spritetype3
  155.   Equz    "program"
  156. .spritetype4
  157.   Equz    "question"
  158. .spritetype5
  159.   Equz    "watchdog"
  160. .ptr_default
  161.   Equz    "ptr_default"
  162.   Align
  163. .error_badmessages
  164.   Equd    0
  165. 3  Equz    "3DErrorWindow Messages file missing"
  166.   Align
  167. .error_nowindow
  168.   Equd    0
  169. 4  Equz    "3DErrorWindow Error template missing"
  170.   Align
  171. .mod_init
  172.   StmFd   R13!,{R0-R4,R14}
  173. !  Mov     R0,#os_module_claim
  174.   Mov     R3,#w
  175.    Add     R3,R3,#scratchsize
  176.   Swi     "XOS_Module"
  177.   AddVs   R13,R13,#4
  178. V  LdmVsFd R13!,{R1-R4,Pc}                                   ; claim some workspace
  179.   Str     R2,[R12]
  180.   Mov     R12,R2
  181.   Add     R0,R12,#w
  182. '  Str     R0,[R12,#wk_scratchblock]
  183.   Mov     R0,#0
  184. #  Str     R0,[R12,#wk_threaded]
  185. &  Str     R0,[R12,#wk_windowblock]
  186. [  Str     R0,[R12,#wk_indirblock]                           ; initialise some workspace
  187.   Mov     R0,#os_file_info
  188.   AdrL    R1,messagesfile
  189.   Swi     "XOS_File"
  190.   BVs     badinit
  191.   Teq     R0,#1
  192. "  AdrNe   R0,error_badmessages
  193.   BNe     badinit
  194. !  Mov     R0,#os_module_claim
  195.   Add     R3,R4,#1
  196.   Swi     "XOS_Module"
  197.   BVs     badinit
  198. (  Str     R2,[R12,#wk_messagesblock]
  199.   Mov     R0,#os_file_load
  200.   AdrL    R1,messagesfile
  201.   Mov     R3,#0
  202.   Swi     "XOS_File"
  203.   BVs     badinit
  204. (  Ldr     R2,[R12,#wk_messagesblock]
  205.   Mov     R0,#0
  206. ]  StrB    R0,[R2,R4]                                        ; load module's Messages file
  207.   AdrL    R1,templatesfile
  208. "  Swi     "XWimp_OpenTemplate"
  209.   BVs     badinit
  210.   Mov     R1,#0
  211.   Mov     R2,#0
  212.   Mov     R3,#0
  213.   Mvn     R4,#0
  214.   AdrL    R5,templatename
  215.   Mov     R6,#0
  216. "  Swi     "XWimp_LoadTemplate"
  217. $  BVs     badinit_closetemplates
  218.   Teq     R0,#0
  219.   AdrEq   R0,error_nowindow
  220. $  BEq     badinit_closetemplates
  221.   Add     R4,R2,#4
  222. !  Mov     R0,#os_module_claim
  223.   Add     R3,R1,#4
  224.   Swi     "XOS_Module"
  225. $  BVs     badinit_closetemplates
  226. &  Str     R2,[R12,#wk_windowblock]
  227. !  Mov     R0,#os_module_claim
  228.   Mov     R3,R4
  229.   Swi     "XOS_Module"
  230. $  BVs     badinit_closetemplates
  231. %  Str     R2,[R12,#wk_indirblock]
  232. &  Ldr     R1,[R12,#wk_windowblock]
  233.   Add     R3,R2,R4
  234.   Mvn     R4,#0
  235.   AdrL    R5,templatename
  236.   Mov     R6,#0
  237. "  Swi     "XWimp_LoadTemplate"
  238. $  BVs     badinit_closetemplates
  239. \  Swi     "XWimp_CloseTemplate"                             ; load window into workspace
  240.   Ldr     R0,specialfilter
  241.   Mov     R1,#trappedswi
  242.   Orr     R1,R1,#1<<31
  243.   Mov     R2,R12
  244.   Adr     R3,reporterror
  245.   Mov     R4,#0
  246. %$  Swi     "XWimp_RegisterFilter"
  247. &\  BVs     badinit                                           ; claim SWI Wimp_ReportError
  248.   LdmFd   R13!,{R0-R4,Pc}^
  249. .badinit_closetemplates
  250.   Mov     R4,R0
  251. +#  Swi     "XWimp_CloseTemplate"
  252.   Mov     R0,R4
  253. .badinit
  254.   Mov     R4,R0
  255. /&  Ldr     R2,[R12,#wk_windowblock]
  256.   Teq     R2,#0
  257. 1#  MovNe   R0,#os_module_release
  258.   SwiNe   "XOS_Module"
  259. 3%  Ldr     R2,[R12,#wk_indirblock]
  260.   Teq     R2,#0
  261. 5#  MovNe   R0,#os_module_release
  262.   SwiNe   "XOS_Module"
  263. 7#  Mov     R0,#os_module_release
  264.   Mov     R2,R12
  265. 9\  Swi     "XOS_Module"                                      ; free any workspace claimed
  266.   Mov     R0,R4
  267.   Add     R13,R13,#4
  268.   LdmFd   R13!,{R1-R4,R14}
  269. =R  OrrS    Pc,R14,#1<<vbit                                   ; and report error
  270. .mod_quit
  271.   StmFd   R13!,{R0-R3,R14}
  272.   Ldr     R12,[R12]
  273.   Ldr     R0,specialfilter
  274.   Mov     R1,#trappedswi
  275.   Mov     R2,R12
  276.   Adr     R3,reporterror
  277.   Mov     R4,#0
  278. G^  Swi     "XWimp_RegisterFilter"                            ; release SWI Wimp_ReportError
  279. H#  Mov     R0,#os_module_release
  280.   Mov     R2,R12
  281. JS  Swi     "XOS_Module"                                      ; release workspace
  282.   LdmFd   R13!,{R0-R3,Pc}^
  283. .mod_service
  284.   Teq     R1,#&27
  285.   MovNeS  Pc,R14
  286.   StmFd   R13!,{R0-R2,R14}
  287.   Adr     R0,callback
  288.   Adr     R12,mod_title
  289. So  LdmFd   R13!,{R0-R2,Pc}^                                  ; for various reasons, we can't survive a reset
  290. .callback
  291.   StmFd   R13!,{R0,R1,R14}
  292. W   Mov     R0,#os_module_quit
  293.   Mov     R1,R12
  294.   Swi     "XOS_Module"
  295.   LdmFd   R13!,{R0,R1,Pc}^
  296. .reporterror
  297.   StmFd   R13!,{R0-R7,R14}
  298. ^$  Ldr     R14,[R12,#wk_threaded]
  299.   Teq     R14,#0
  300.   LdmNeFd R13!,{R0-R7,Pc}^
  301.   Mov     R14,#1
  302. b$  Str     R14,[R12,#wk_threaded]
  303.   Tst     R1,#(1<<5)+(1<<6)
  304.   TstEq   R1,#1<<31
  305. eg  BNe     reporterror_passon                                ; we can't deal with these funny events
  306.   LdmFd   R13!,{R2-R7}
  307. g#  AdrL    R1,serv_errorstarting
  308.   Ldr     R1,[R1]
  309.   Swi     "XOS_ServiceCall"
  310. jq  StmFd   R13!,{R2-R7}                                      ; allow Service_ErrorStarting to change registers
  311. .anothererror_jumpin
  312.   Ldr     R1,[R13,#4]
  313.   Tst     R1,#(1<<5)+(1<<6)
  314.   TstEq   R1,#1<<31
  315. og  BNe     reporterror_passon                                ; we can't deal with these funny events
  316.   Ldr     R0,[R13]
  317.   Ldr     R0,[R0]
  318.   Tst     R0,#1<<31
  319. sp  BEq     doerrorystuff                                     ; skip this next rubbish unless a fatalish error
  320.   Tst     R1,#1<<4
  321.   LdrNe   R0,[R13,#8]
  322.   BNe     taskname_string
  323. w'  Mov     R0,#wimp_readsysinfo_task
  324. x!  Swi     "XWimp_ReadSysInfo"
  325.   BVs     doerrorystuff
  326.   Teq     R0,#0
  327. {/  SwiNe   "XTaskManager_TaskNameFromHandle"
  328.   TeqVs   R0,R0
  329.   LdrEq   R0,[R13,#8]
  330.   Cmn     R0,#1
  331.   BEq     taskname_unknown
  332. .taskname_string
  333.   Cmn     R0,#1
  334.   BEq     taskname_unknown
  335. '  Ldr     R1,[R12,#wk_scratchblock]
  336.   Mov     R14,#0
  337.   Str     R14,[R1],#4
  338.     .loop
  339.   LdrB    R2,[R0],#1
  340.   Cmp     R2,#32
  341.   StrPlB  R2,[R1],#1
  342.   BPl     loop
  343.   Mov     R0,R1
  344.   B       taskname_got
  345. .taskname_unknown
  346. '  Ldr     R0,[R12,#wk_scratchblock]
  347.   Mov     R14,#0
  348.   Str     R14,[R0],#4
  349. (  Ldr     R1,[R12,#wk_messagesblock]
  350.   AdrL    R2,t_unknowntask
  351.   Bl      translate
  352.   BVs     doerrorystuff
  353. t  Sub     R0,R2,#1                                          ; get app name (title or task or unknown) into block
  354. .taskname_got
  355. (  Ldr     R1,[R12,#wk_messagesblock]
  356.   AdrL    R2,t_baderror
  357.   Bl      translate
  358. k  BVs     doerrorystuff                                     ; copy the rest of the error message across
  359. '  Ldr     R0,[R12,#wk_scratchblock]
  360.   Ldr     R1,[R13,#4]
  361.   Tst     R1,#1<<1
  362.   MovEq   R14,#1
  363.   MovNe   R14,#0
  364. /  Str     R14,[R12,#wk_baderrorcanceladded]
  365.   Orr     R1,R1,#1<<1
  366.   Bic     R1,R1,#1<<2
  367.   Tst     R1,#1<<8
  368.   Orr     R1,R1,#1<<8
  369.   Bic     R1,R1,#7<<9
  370.   Orr     R1,R1,#3<<9
  371.   Orr     R1,R1,#1<<31
  372.   Ldr     R2,[R13,#8]
  373.   Ldr     R3,[R13,#12]
  374.   Ldr     R4,[R13,#16]
  375.   MovEq   R3,#0
  376.   MovEq   R4,#1
  377. )  Adr     R14,backafterfirstrequester
  378.   Mov     R5,Pc
  379.   And     R5,R5,#&FC000003
  380.   Orr     R14,R14,R5
  381.   Ldr     R5,[R13,#20]
  382.   MovEq   R5,#0
  383.   StmFd   R13!,{R9}
  384.   StmFd   R13!,{R0-R7,R14}
  385. r  B       doerrorystuff                                     ; do a preliminary requester with 'Describe' on it
  386. .backafterfirstrequester
  387.   Mov     R0,#1
  388. #  Str     R0,[R12,#wk_threaded]
  389.   Cmn     R9,#1
  390.   LdmFd   R13!,{R9}
  391.    BNe     reporterror_passon
  392. .  Ldr     R0,[R12,#wk_baderrorcanceladded]
  393.   Teq     R0,#1
  394.   MovEq   R14,#0
  395. $  StrEq   R14,[R12,#wk_threaded]
  396.   TeqEq   R1,#2
  397. n  SwiEq   "OS_Exit"                                         ; if 'cancel' clicked and we added it, we quit
  398.   Cmn     R1,#1
  399.   MovNe   R14,#0
  400. $  StrNe   R14,[R12,#wk_threaded]
  401.   MvnNe   R9,#0
  402.   AddNe   R13,R13,#8
  403. q  LdmNeFd R13!,{R2-R7,Pc}^                                  ; if 'describe', now show real error, else return
  404. .doerrorystuff
  405.   Ldr     R0,[R13]
  406.   Add     R0,R0,#4
  407. s  Mov     R1,#icon_message                                  ; copy error message to message icon - ignore error
  408. `  Bl      seticonstring                                     ; from Wimp_TextOp as irrelevent
  409. '  Mov     R0,#wimp_readsysinfo_task
  410. !  Swi     "XWimp_ReadSysInfo"
  411.    BVs     reporterror_passon
  412.   Teq     R0,#0
  413.   MvnNe   R0,#0
  414. )  StrNe   R0,[R12,#wk_temptaskhandle]
  415.   BNe     gotatask
  416.   Mov     R0,#wimpinitver
  417.   AdrL    R1,wimptask
  418.   Ldr     R1,[R1]
  419.   AdrL    R2,mod_title
  420.    Swi     "XWimp_Initialise"
  421.    BVs     reporterror_passon
  422. s  Str     R0,[R12,#wk_temptaskhandle]                       ; if we're outside the WIMP, start a temporary task
  423. .gotatask
  424.   Ldr     R1,[R13,#4]
  425.   Tst     R1,#1<<4
  426.   LdrNe   R0,[R13,#8]
  427. r  BNe     copytotitle                                       ; if bit 4 is set, we don't have to use do this...
  428.   Tst     R1,#1<<8
  429. !  AdrEqL  R0,t_oldtitleprefix
  430.   BEq     gotprefix
  431.   And     R1,R1,#7<<9
  432.   Mov     R1,R1,Lsr#9
  433.   AndS    R1,R1,#7
  434. "  AdrEqL  R0,t_newtitleprefix0
  435.   Teq     R1,#1
  436. "  AdrEqL  R0,t_newtitleprefix1
  437.   Teq     R1,#2
  438. "  AdrEqL  R0,t_newtitleprefix2
  439.   Teq     R1,#3
  440. "  AdrEqL  R0,t_newtitleprefix3
  441.   Teq     R1,#4
  442. "  AdrEqL  R0,t_newtitleprefix4
  443.   Cmp     R1,#5
  444. "  AdrEqL  R0,t_newtitleprefix5
  445. !  AdrGtL  R0,t_oldtitleprefix
  446. s.gotprefix                                                  ; find which title prefix to use according to flags
  447.   Mov     R2,R0
  448. (  Ldr     R1,[R12,#wk_messagesblock]
  449. '  Ldr     R0,[R12,#wk_scratchblock]
  450.   Bl      translate
  451. %  BVs     reporterror_passon_quit
  452.   Ldr     R1,[R13,#8]
  453.   Cmn     R1,#1
  454. '  LdrEq   R0,[R12,#wk_scratchblock]
  455.   BEq     copytotitle
  456.   Sub     R0,R2,#1
  457. (  Ldr     R1,[R12,#wk_messagesblock]
  458.   AdrL    R2,t_titlefrom
  459.   Bl      translate
  460. %  BVs     reporterror_passon_quit
  461.   Sub     R1,R2,#1
  462.   Ldr     R0,[R13,#8]
  463.     .loop
  464.   LdrB    R14,[R0],#1
  465.   Cmp     R14,#32
  466.   MovMi   R14,#0
  467.   StrB    R14,[R1],#1
  468.   BPl     loop
  469.     r  Ldr     R0,[R12,#wk_scratchblock]                         ; copy prefix and appname (if supplied) to a block
  470. .copytotitle
  471.   Mov     R1,#icon_title
  472.   Bl      seticonstring
  473. T  BVs     reporterror_passon_quit                           ; copy title to icon
  474.   Add     R1,R0,#48
  475. !  Mov     R0,#icon_innerframe
  476.   Bl      geticonwidth
  477.   SubS    R0,R0,#22
  478.   Cmp     R0,R1
  479.   MovMi   R1,R0
  480.   Mov     R0,#icon_title
  481. Z  Bl      seticonwidth                                      ; make text fit icon width
  482. &  Ldr     R0,[R12,#wk_windowblock]
  483.   Add     R0,R0,#88
  484. "  Add     R1,R0,#32*icon_title
  485.   Ldr     R1,[R1,#8]
  486. &  Add     R2,R0,#32*icon_titlejoin
  487.   Ldr     R3,[R2]
  488.   Ldr     R4,[R2,#8]
  489.   Sub     R3,R4,R3
  490.   Str     R1,[R2,#8]
  491.   Sub     R3,R1,R3
  492.  u  Str     R3,[R2]                                           ; right-align the title join to the edge of the title
  493.   Ldr     R1,[R13,#4]
  494.   Tst     R1,#1<<8
  495.   MovEq   R1,#0
  496.   AndNe   R1,R1,#7<<9
  497.   MovNe   R1,R1,Lsr#9
  498.   Mov     R0,#colour_red
  499.   Teq     R1,#1
  500.   MovEq   R0,#colour_green
  501.   Teq     R1,#2
  502.   MovEq   R0,#colour_red
  503.   Teq     R1,#3
  504.   MovEq   R0,#colour_red
  505.   Teq     R1,#4
  506.   MovEq   R0,#colour_blue
  507.   Teq     R1,#5
  508. 0]  MovEq   R0,#colour_red                                    ; get colour to use on window
  509. 1&  Ldr     R1,[R12,#wk_windowblock]
  510.   Add     R1,R1,#88
  511. 3&  Add     R1,R1,#32*icon_colourbox
  512.   Ldr     R2,[R1,#16]
  513.   Bic     R2,R2,#&FF000000
  514.   Orr     R2,R2,R0,Lsl#24
  515.   Orr     R2,R2,R0,Lsl#28
  516. 8X  Str     R2,[R1,#16]                                       ; set the coloured frame
  517.   Ldr     R1,[R13,#4]
  518.   Tst     R1,#1<<8
  519.   MovEq   R1,#0
  520.   AndNe   R1,R1,#7<<9
  521.   MovNe   R1,R1,Lsr#9
  522.   AdrL    R0,spritetype0
  523.   Teq     R1,#1
  524.   AdrEqL  R0,spritetype1
  525.   Teq     R1,#2
  526.   AdrEqL  R0,spritetype2
  527.   Teq     R1,#3
  528.   AdrEqL  R0,spritetype3
  529.   Teq     R1,#4
  530.   AdrEqL  R0,spritetype4
  531.   Teq     R1,#5
  532. HQ  AdrEqL  R0,spritetype5                                    ; get sprite type
  533.   Mov     R1,#icon_typeicon
  534.   Bl      seticonstring
  535. KU  BVs     reporterror_passon_quit                           ; set the type sprite
  536. L&  Ldr     R0,[R12,#wk_windowblock]
  537.   Add     R0,R0,#88
  538. N(  Add     R0,R0,#32*icon_firstbutton
  539. O!  Mov     R1,#numberofbuttons
  540. P    .loop
  541.   Ldr     R2,[R0,#16]!
  542. R(  Orr     R2,R2,#1<<iconflag_deleted
  543.   Str     R2,[R0],#16
  544.   SubS    R1,R1,#1
  545.   BNe     loop
  546.   Mov     R0,#0
  547. W*  Str     R0,[R12,#wk_numberofbuttons]
  548.   Mvn     R0,#0
  549. Y*  Str     R0,[R12,#wk_firstuserbutton]
  550. Z)  Str     R0,[R12,#wk_describebutton]
  551. [$  Mov     R0,#minimumbuttonwidth
  552. \j  Str     R0,[R12,#wk_buttonwidth]                          ; initialise window with no buttons at all
  553.   Ldr     R0,[R13,#4]
  554.   And     R1,R0,#7
  555.   Tst     R1,#4
  556.   TeqNe   R1,#7
  557. au  BicNe   R1,R1,#4                                          ; flags bit 2 is irrelevant unless both OK and Cancel
  558.   Tst     R0,#1<<8
  559.   LdrNe   R14,[R13,#20]
  560.   TeqNe   R14,#0
  561. eo  TeqEq   R1,#0                                             ; on an old system, or where there are no extra
  562. fu  MovEq   R1,#1                                             ; buttons, we must ensure we have at least one button
  563.   Teq     R1,#7
  564.   BlEq    addcancelbutton
  565.   BlEq    addokbutton
  566. jp  BEq     addedsystembuttons                                ; if flags bit 2, then Cancel is default, not OK
  567.   Tst     R1,#1
  568.   BlNe    addokbutton
  569.   Tst     R1,#2
  570.   BlNe    addcancelbutton
  571. .addedsystembuttons
  572. p*  Ldr     R0,[R12,#wk_numberofbuttons]
  573. qp  Str     R0,[R12,#wk_firstuserbutton]                      ; we've now added all system buttons (OK/Cancel)
  574.   Ldr     R1,[R13,#4]
  575.   Tst     R1,#1<<8
  576.   BEq     addedextrabuttons
  577.   Ldr     R6,[R13,#20]
  578.   Teq     R6,#0
  579. wn  BEq     addedextrabuttons                                 ; only add extra buttons when they're supplied
  580. .buttonloop
  581. y'  Ldr     R1,[R12,#wk_scratchblock]
  582. z    .loop
  583.   LdrB    R0,[R6],#1
  584.   Cmp     R0,#32
  585.   MovMi   R0,#0
  586.   Teq     R0,#
  587. (",")
  588.   MovEq   R0,#0
  589.   StrB    R0,[R1],#1
  590.   Teq     R0,#0
  591.   BNe     loop
  592. '  Ldr     R0,[R12,#wk_scratchblock]
  593.   Bl      addabutton
  594. %  BVs     reporterror_passon_quit
  595.   LdrB    R0,[R6,#-1]
  596.   Cmp     R0,#32
  597. i  BPl     buttonloop                                        ; add all buttons in comma separated list
  598. .addedextrabuttons
  599.   Ldr     R0,[R13,#4]
  600.   Tst     R0,#1<<31
  601.   BEq     addedallbuttons
  602. *  Ldr     R0,[R12,#wk_numberofbuttons]
  603. )  Str     R0,[R12,#wk_describebutton]
  604. '  Ldr     R0,[R12,#wk_scratchblock]
  605. (  Ldr     R1,[R12,#wk_messagesblock]
  606.   AdrL    R2,t_describe
  607.   Bl      translate
  608. %  BVs     reporterror_passon_quit
  609.   Bl      addabutton
  610. m  BVs     reporterror_passon_quit                           ; add a Describe button if entirely necessary
  611. .addedallbuttons
  612. *  Ldr     R2,[R12,#wk_numberofbuttons]
  613. "  Mov     R0,#icon_firstbutton
  614. &  Ldr     R1,[R12,#wk_buttonwidth]
  615.   Add     R1,R1,#24
  616.     .loop
  617.   Bl      seticonwidth
  618.   Add     R0,R0,#1
  619. &  Ldr     R1,[R12,#wk_buttonwidth]
  620.   Add     R1,R1,#8
  621.   SubS    R2,R2,#1
  622. e  BNe     loop                                              ; make all the buttons the right size
  623. &  Ldr     R1,[R12,#wk_windowblock]
  624.   Add     R1,R1,#88
  625. (  Add     R2,R1,#32*icon_firstbutton
  626.   Ldr     R0,[R2,#8]
  627.   Add     R0,R0,#10
  628. &  Add     R2,R1,#32*icon_colourbox
  629.   Str     R0,[R2,#8]
  630.   Add     R0,R0,#4
  631. &  Ldr     R1,[R12,#wk_windowblock]
  632. q  Str     R0,[R1,#48]                                       ; make containing box and window size fit buttons
  633. &  Ldr     R0,[R12,#wk_windowblock]
  634.   Add     R0,R0,#88
  635. %  Add     R1,R0,#32*icon_typeicon
  636.   Ldr     R2,[R1,#16]
  637. (  Orr     R2,R2,#1<<iconflag_deleted
  638.   Str     R2,[R1,#16]
  639. (  Add     R1,R0,#32*icon_application
  640.   Ldr     R2,[R1,#16]
  641. (  Orr     R2,R2,#1<<iconflag_deleted
  642. c  Str     R2,[R1,#16]                                       ; delete both sprites to initialise
  643. *  Ldr     R0,[R12,#wk_numberofbuttons]
  644. *  Cmp     R0,#buttonthatdeletessprites
  645. u  BPl     donesprites                                       ; if we have lots of buttons, there's no sprite space
  646. &  Ldr     R0,[R12,#wk_windowblock]
  647.   Add     R0,R0,#88
  648. %  Add     R1,R0,#32*icon_typeicon
  649.   Ldr     R2,[R1,#16]
  650. (  Bic     R2,R2,#1<<iconflag_deleted
  651. [  Str     R2,[R1,#16]                                       ; ok, so undelete type icon
  652.   Ldr     R1,[R13,#4]
  653.   Ldr     R2,[R13,#8]
  654.   Ldr     R3,[R13,#12]
  655.   Ldr     R4,[R13,#16]
  656.   Tst     R1,#1<<8
  657.   TeqNe   R3,#0
  658.   CmnNe   R3,#1
  659.   TeqNe   R4,#0
  660.   CmnNe   R4,#1
  661. t  BNe     gotappsprite                                      ; if a sprite is specified, we don't need to find it
  662.   Cmn     R2,#1
  663. #  BEq     definitelynoappsprite
  664. '  Ldr     R1,[R12,#wk_scratchblock]
  665.   Mov     R0,#
  666. ("!")
  667.   StrB    R0,[R1],#1
  668.     .loop
  669.   LdrB    R0,[R2],#1
  670.   Cmp     R0,#32
  671.   MovMi   R0,#0
  672.   StrB    R0,[R1],#1
  673.   BPl     loop
  674. $  Mov     R0,#os_spriteop_select
  675. '  Ldr     R2,[R12,#wk_scratchblock]
  676.   Swi     "XWimp_SpriteOp"
  677. '  LdrVc   R3,[R12,#wk_scratchblock]
  678.   MovVc   R4,#1
  679. p  BVc     gotappsprite                                      ; none specified? Try !<errortitle> in WIMP pool
  680.   Ldr     R0,[R13,#4]
  681. "  And     R0,R0,#(1<<8)+(7<<9)
  682.   Teq     R0,#(1<<8)+(5<<9)
  683. v  BEq     definitelynoappsprite                             ; if watchdog, the current task can't be used, else...
  684. '  Mov     R0,#wimp_readsysinfo_task
  685. !  Swi     "XWimp_ReadSysInfo"
  686. #  BVs     definitelynoappsprite
  687.   Teq     R0,#0
  688. #  BEq     definitelynoappsprite
  689. /  Swi     "XTaskManager_TaskNameFromHandle"
  690. #  BVs     definitelynoappsprite
  691.   Mov     R2,R0
  692. '  Ldr     R1,[R12,#wk_scratchblock]
  693.   Mov     R0,#
  694. ("!")
  695.   StrB    R0,[R1],#1
  696.     .loop
  697.   LdrB    R0,[R2],#1
  698.   Cmp     R0,#32
  699.   BEq     loop
  700.   MovMi   R0,#0
  701.   StrB    R0,[R1],#1
  702.   BPl     loop
  703. $  Mov     R0,#os_spriteop_select
  704. '  Ldr     R2,[R12,#wk_scratchblock]
  705.   Swi     "XWimp_SpriteOp"
  706. '  LdrVc   R3,[R12,#wk_scratchblock]
  707.   MovVc   R4,#1
  708. p  BVc     gotappsprite                                      ; ...try !<taskname without spaces> in WIMP pool
  709. .definitelynoappsprite
  710. &  Ldr     R0,[R12,#wk_windowblock]
  711.   Add     R0,R0,#88
  712. (  Add     R1,R0,#32*icon_firstbutton
  713.   Ldr     R2,[R1]
  714.   Ldr     R3,[R1,#8]
  715.   Sub     R3,R3,R2
  716.   Add     R2,R2,R3,Lsr#1
  717.   Bic     R2,R2,#1
  718. %  Add     R1,R0,#32*icon_typeicon
  719.   Ldr     R3,[R1]
  720.   Ldr     R4,[R1,#8]
  721.   Sub     R3,R4,R3
  722.   Sub     R2,R2,R3,Lsr#1
  723.   Str     R2,[R1]
  724.   Add     R2,R2,R3
  725.   Str     R2,[R1,#8]
  726. u  B       donesprites                                       ; can't get any spritename? Then centre the type icon
  727. .gotappsprite
  728.   Mov     R0,R3
  729. "  Mov     R1,#icon_application
  730.   Bl      seticonstring
  731. &  Ldr     R0,[R12,#wk_windowblock]
  732.   Add     R0,R0,#88
  733. %  Add     R1,R0,#32*icon_typeicon
  734. (  Add     R2,R0,#32*icon_application
  735.   Ldr     R14,[R2,#16]
  736. *  Bic     R14,R14,#1<<iconflag_deleted
  737.   Str     R14,[R2,#16]
  738. t  Str     R4,[R2,#24]                                       ; copy sprite name/pointer to app icon, and undelete
  739. (  Add     R0,R0,#32*icon_firstbutton
  740.   Ldr     R3,[R0]
  741.   Ldr     R4,[R0,#8]
  742.   Sub     R4,R4,R3
  743.   Add     R3,R3,R4,Lsr#1
  744.   Bic     R0,R3,#1
  745.   Ldr     R3,[R1]
  746.   Ldr     R4,[R1,#8]
  747.   Sub     R3,R4,R3
  748. -  Sub     R14,R0,#twospriteseparation 
  749.   Str     R14,[R1,#8]
  750.   Sub     R14,R14,R3
  751.   Str     R14,[R1]
  752.   Ldr     R3,[R2]
  753.   Ldr     R4,[R2,#8]
  754.   Sub     R4,R4,R3
  755. $-  Add     R14,R0,#twospriteseparation 
  756.   Str     R14,[R2]
  757.   Add     R14,R14,R4
  758. '`  Str     R14,[R2,#8]                                       ; if two icons, centre them both
  759. .donesprites
  760. )&  Ldr     R1,[R12,#wk_windowblock]
  761.   Ldr     R3,[R1,#40]
  762.   Ldr     R4,[R1,#44]
  763.   Ldr     R5,[R1,#48]
  764.   Ldr     R6,[R1,#52]
  765.   Sub     R5,R5,R3
  766.   Sub     R6,R6,R4
  767.   Mvn     R0,#0
  768.   Mov     R1,#modevar_xpix
  769. 2$  Swi     "XOS_ReadModeVariable"
  770.   Add     R3,R2,#1
  771.   Mvn     R0,#0
  772.   Mov     R1,#modevar_ypix
  773. 6$  Swi     "XOS_ReadModeVariable"
  774.   Add     R4,R2,#1
  775.   Mvn     R0,#0
  776.   Mov     R1,#modevar_xeig
  777. :$  Swi     "XOS_ReadModeVariable"
  778.   Mov     R3,R3,LslR2
  779.   Mvn     R0,#0
  780.   Mov     R1,#modevar_yeig
  781. >$  Swi     "XOS_ReadModeVariable"
  782.   Mov     R4,R4,LslR2
  783. @&  Ldr     R1,[R12,#wk_windowblock]
  784.   SubS    R0,R3,R5
  785.   Mov     R0,R0,Asr#1
  786.   Str     R0,[R1,#0]
  787.   Add     R0,R0,R5
  788.   Str     R0,[R1,#8]
  789.   SubS    R0,R4,R6
  790.   Mov     R0,R0,Asr#1
  791.   Str     R0,[R1,#4]
  792.   Add     R0,R0,R6
  793. J_  Str     R0,[R1,#12]                                       ; centre error window to screen
  794. K"  Swi     "XWimp_CreateWindow"
  795. L%  BVs     reporterror_passon_quit
  796. MY  Str     R0,[R12,#wk_windowhandle]                         ; create our error window
  797.   Mov     R0,#1
  798. O%  Mov     R1,#service_reporterror
  799. P_  Swi     "XOS_ServiceCall"                                 ; send out another service call
  800.   Mvn     R0,#0
  801. Rl  Swi     "XWimp_CommandWindow"                             ; in case, for example a filer rename errors
  802. S+  Mov     R0,#os_spriteop_switchcontext
  803.   Mov     R1,#0
  804.   Mov     R2,#0
  805.   Mov     R3,#1
  806. Wq  Swi     "XOS_SpriteOp"                                    ; switch output to screen if in a sprite ATM, 004
  807. X"  Mov     R0,#os_byte_readcmos
  808. Y   Mov     R1,#cmos_wimpflags
  809.   Swi     "XOS_Byte"
  810.   Ldr     R1,[R13,#4]
  811.   Tst     R1,#1<<7
  812.   TstEq   R2,#1<<4
  813. ^r  SwiEq   XOS_WriteI+7                                      ; beep, unless CMOS or application tells us not to
  814. _T  Swi     "XHourglass_Smash"                                ; turn hourglass off
  815. `'  Ldr     R1,[R12,#wk_scratchblock]
  816. a'  Ldr     R0,[R12,#wk_windowhandle]
  817.   Str     R0,[R1]
  818. c$  Swi     "XWimp_GetWindowState"
  819. d-  BVs     reporterror_passon_deletewindow
  820.   Mvn     R0,#0
  821.   Str     R0,[R1,#28]
  822. g   Swi     "XWimp_OpenWindow"
  823. hT  BVs     reporterror_passon_deletewindow                   ; open it at the top
  824. i"  Swi     "XWimp_RedrawWindow"
  825. j    .loop
  826.   Teq     R0,#0
  827. l"  SwiNe   "XWimp_GetRectangle"
  828. mg  BNe     loop                                              ; make the Wimp redraw it straight away
  829. n'  Ldr     R1,[R12,#wk_scratchblock]
  830. o'  Ldr     R0,[R12,#wk_windowhandle]
  831.   Str     R0,[R1]
  832. q%  Swi     "Wimp_GetWindowOutline"
  833.   Ldr     R2,[R1,#4]
  834.   Ldr     R3,[R1,#8]
  835.   Ldr     R4,[R1,#12]
  836.   Ldr     R5,[R1,#16]
  837.   Sub     R5,R5,#1
  838.   Sub     R4,R4,#1
  839.   Mov     R6,#255
  840. y$  Mov     R0,#os_word_mouse_bbox
  841.   StrB    R0,[R1,#0]
  842.   And     R0,R6,R2
  843.   StrB    R0,[R1,#1]
  844.   And     R0,R6,R2,Lsr#8
  845.   StrB    R0,[R1,#2]
  846.   And     R0,R6,R3
  847.   StrB    R0,[R1,#3]
  848.   And     R0,R6,R3,Lsr#8
  849.   StrB    R0,[R1,#4]
  850.   And     R0,R6,R4
  851.   StrB    R0,[R1,#5]
  852.   And     R0,R6,R4,Lsr#8
  853.   StrB    R0,[R1,#6]
  854.   And     R0,R6,R5
  855.   StrB    R0,[R1,#7]
  856.   And     R0,R6,R5,Lsr#8
  857.   StrB    R0,[R1,#8]
  858.   Mov     R0,#os_word_mouse
  859. \  Swi     "XOS_Word"                                        ; confine mouse to error box
  860. "  Mov     R0,#os_byte_ptrshape
  861.   Mov     R1,#1
  862.   Swi     "XOS_Byte"
  863. k  Str     R1,[R12,#wk_oldptrshape]                          ; make sure pointer's displayed and shape 1
  864. (  Mov     R0,#os_spriteop_setpointer
  865.   AdrL    R2,ptr_default
  866.   Mov     R3,#1
  867.   Mov     R4,#0
  868.   Mov     R5,#0
  869.   Mov     R6,#0
  870.   Mov     R7,#0
  871. l  Swi     "XWimp_SpriteOp"                                  ; make sure we have the normal pointer shape
  872.     .loop
  873. "  Mov     R0,#os_byte_scankeys
  874.   Mov     R1,#9
  875.   Swi     "XOS_Byte"
  876.   Teq     R1,#&FF
  877.   BNe     loop
  878. +  Mov     R0,#os_byte_acknowledgeescape
  879.   Swi     "XOS_Byte"
  880.   Mov     R0,#os_byte_flush
  881. !  Mov     R1,#buffer_keyboard
  882.   Swi     "XOS_Byte"
  883.   Mov     R0,#os_byte_flush
  884.   Mov     R1,#buffer_mouse
  885. [  Swi     "XOS_Byte"                                        ; clear out any old rubbish
  886. .interactionloop
  887. "  Mov     R0,#os_byte_readkeys
  888.   Mov     R1,#0
  889.   Mov     R2,#0
  890.   Swi     "XOS_Byte"
  891.   Teq     R2,#0
  892.   TeqEq   R1,#13
  893.   BEq     pressedreturn
  894.   Teq     R2,#0
  895.   TeqEq   R1,#27
  896.   TeqNe   R2,#27
  897. f  BEq     pressedescape                                     ; make Return and Escape press buttons
  898.   Swi     "XOS_Mouse"
  899.   BicS    R2,R2,#2
  900.   BEq     interactionloop
  901.   Mov     R2,R0
  902.   Mov     R3,R1
  903. '  Ldr     R1,[R12,#wk_scratchblock]
  904. '  Ldr     R0,[R12,#wk_windowhandle]
  905.   Str     R0,[R1]
  906. $  Swi     "XWimp_GetWindowState"
  907.   Ldr     R4,[R1,#4]
  908.   Ldr     R5,[R1,#20]
  909.   Sub     R4,R4,R5
  910.   Sub     R2,R2,R4
  911.   Ldr     R4,[R1,#16]
  912.   Ldr     R5,[R1,#24]
  913.   Sub     R4,R4,R5
  914. p  Sub     R3,R3,R4                                          ; get mouse co-ords relative to work area origin
  915. "  Mov     R4,#icon_firstbutton
  916. *  Ldr     R5,[R12,#wk_numberofbuttons]
  917.     .loop
  918.   Str     R4,[R1,#4]
  919. "  Swi     "XWimp_GetIconState"
  920.   Ldr     R6,[R1,#8]
  921.   Cmp     R2,R6
  922.   LdrPl   R6,[R1,#16]
  923.   CmpPl   R6,R2
  924.   LdrPl   R6,[R1,#12]
  925.   CmpPl   R3,R6
  926.   LdrPl   R6,[R1,#20]
  927.   CmpPl   R6,R3
  928.   MovPl   R0,R4
  929.   BPl     clickedsummat
  930.   Add     R4,R4,#1
  931.   SubS    R5,R5,#1
  932. g  BNe     loop                                              ; check to see if a click hits a button
  933.   B       interactionloop
  934. .pressedreturn
  935. "  Mov     R0,#icon_firstbutton
  936.   B       clickedsummat
  937. .pressedescape
  938. +  Mov     R0,#os_byte_acknowledgeescape
  939.   Swi     "XOS_Byte"
  940. *  Ldr     R0,[R12,#wk_numberofbuttons]
  941.   Cmp     R0,#2
  942. $  MovPl   R0,#icon_firstbutton+1
  943. "  MovMi   R0,#icon_firstbutton
  944.   B       clickedsummat
  945. .clickedsummat
  946.   Mov     R7,R0
  947. '  Ldr     R1,[R12,#wk_scratchblock]
  948. '  Ldr     R0,[R12,#wk_windowhandle]
  949.   Str     R0,[R1]
  950.   Str     R7,[R1,#4]
  951. &  Mov     R0,#1<<iconflag_selected
  952.   Str     R0,[R1,#8]
  953.   Str     R0,[R1,#12]
  954. _  Swi     "XWimp_SetIconState"                              ; pop the clicked icon in a bit
  955.   Mvn     R0,#0
  956.   Mov     R1,#modevar_xpix
  957. $  Swi     "XOS_ReadModeVariable"
  958.   Add     R3,R2,#1
  959.   Mov     R1,#modevar_ypix
  960. $  Swi     "XOS_ReadModeVariable"
  961.   Add     R4,R2,#1
  962.   Mov     R1,#modevar_xeig
  963. $  Swi     "XOS_ReadModeVariable"
  964.   Mov     R3,R3,LslR2
  965.   Mov     R1,#modevar_yeig
  966. $  Swi     "XOS_ReadModeVariable"
  967.   Mov     R4,R4,LslR2
  968.   Mov     R6,#255
  969. '  Ldr     R1,[R12,#wk_scratchblock]
  970.   Add     R1,R1,#128
  971. $  Mov     R0,#os_word_mouse_bbox
  972.   StrB    R0,[R1]
  973.   Mov     R0,#0
  974.   StrB    R0,[R1,#1]
  975.   StrB    R0,[R1,#2]
  976.   StrB    R0,[R1,#3]
  977.   StrB    R0,[R1,#4]
  978.   And     R0,R6,R3
  979.   StrB    R0,[R1,#5]
  980.   And     R0,R6,R3,Lsr#8
  981.   StrB    R0,[R1,#6]
  982.   And     R0,R6,R4
  983.   StrB    R0,[R1,#7]
  984.   And     R0,R6,R4,Lsr#8
  985.   StrB    R0,[R1,#8]
  986.   Mov     R0,#os_word_mouse
  987. V  Swi     "XOS_Word"                                        ; stop mouse confining
  988. "  Mov     R0,#os_byte_ptrshape
  989. &  Ldr     R1,[R12,#wk_oldptrshape]
  990. a  Swi     "XOS_Byte"                                        ; restore old mouse linkage/shape
  991.   Mov     R3,Pc
  992.   Bic     R14,R3,#1<<ibit
  993. O  TeqP    R14,#0                                            ; interrupts on
  994. %  Swi     "XOS_ReadMonotonicTime"
  995.    Add     R2,R0,#buttondelay
  996.     .loop
  997. %  Swi     "XOS_ReadMonotonicTime"
  998.   Cmp     R0,R2
  999. t  BMi     loop                                              ; pause a bit to let the user see the popped-in icon
  1000. c  TeqP    R3,#0                                             ; interrupts back to what they were
  1001.   Mov     R0,#0
  1002. %  Mov     R1,#service_reporterror
  1003. h  Swi     "XOS_ServiceCall"                                 ; send out another blummin' service call
  1004.  '  Ldr     R0,[R12,#wk_windowhandle]
  1005. !'  Ldr     R1,[R12,#wk_scratchblock]
  1006.   Str     R0,[R1]
  1007. #Z  Swi     "XWimp_DeleteWindow"                              ; don't need that any more
  1008. $)  Ldr     R0,[R12,#wk_temptaskhandle]
  1009.   Cmn     R0,#1
  1010.   AdrNeL  R1,wimptask
  1011.   LdrNe   R1,[R1]
  1012. (_  SwiNe   "XWimp_CloseDown"                                 ; forget any task we started up
  1013. )%  Sub     R7,R7,#icon_firstbutton
  1014. *)  Ldr     R0,[R12,#wk_describebutton]
  1015.   Teq     R7,R0
  1016.   MvnEq   R1,#0
  1017.   BEq     gotbuttonnumber
  1018. .*  Ldr     R0,[R12,#wk_firstuserbutton]
  1019.   Cmn     R0,#1
  1020.   AddNe   R1,R7,#1
  1021.   BEq     gotokorcancel
  1022.   SubS    R1,R7,R0
  1023.   AddPl   R1,R1,#3
  1024.   AddMi   R1,R7,#1
  1025.   BPl     gotbuttonnumber
  1026. .gotokorcancel
  1027.   Ldr     R0,[R13,#4]
  1028.   And     R0,R0,#7
  1029.   Teq     R0,#7
  1030.   RsbEq   R1,R1,#3
  1031. ;r.gotbuttonnumber                                            ; translate clicked icon number to returned button
  1032.   Ldr     R0,[R13,#4]
  1033.   Tst     R0,#1<<31
  1034.   BNe     notarealend
  1035.   Mov     R0,#0
  1036.   Mov     R2,R1
  1037. A(  AdrL    R1,serv_errorbuttonpressed
  1038.   Ldr     R1,[R1]
  1039.   Ldr     R3,[R13,#20]
  1040.   Swi     "XOS_ServiceCall"
  1041.   Teq     R0,#1
  1042.   MovNe   R1,R2
  1043.   BNe     realend
  1044.   LdmIa   R2,{R0-R5}
  1045.   Add     R13,R13,#24
  1046.   StmFd   R13!,{R0-R5}
  1047. Kp  B       anothererror_jumpin                               ; allow Service_ErrorButtonPressed to muck about
  1048. .realend
  1049.   Mov     R2,R1
  1050. N!  AdrL    R1,serv_errorending
  1051.   Ldr     R1,[R1]
  1052.   Swi     "XOS_ServiceCall"
  1053. Qi  Mov     R1,R2                                             ; another completely bizarre service call
  1054. .notarealend
  1055.   Add     R13,R13,#8
  1056.   Mvn     R9,#0
  1057.   Mov     R14,#0
  1058. V$  Str     R14,[R12,#wk_threaded]
  1059. Wt  LdmFd   R13!,{R2-R7,Pc}^                                  ; tell WimpSWIVe to intercept, supplying result regs
  1060. Ys.reporterror_passon_deletewindow                            ; we pass on to the standard wimp error window if a
  1061. Zt  Ldr     R0,[R12,#wk_windowhandle]                         ; situation we can't handle arises - >6 buttons, too
  1062. [u  Ldr     R1,[R12,#wk_scratchblock]                         ; long buttons, title that won't fit in its box, etc.
  1063.   Str     R0,[R1]
  1064. ]"  Swi     "XWimp_DeleteWindow"
  1065. .reporterror_passon_quit
  1066. _)  Ldr     R0,[R12,#wk_temptaskhandle]
  1067.   Cmn     R0,#1
  1068.   AdrNeL  R1,wimptask
  1069.   LdrNe   R1,[R1]
  1070. c_  SwiNe   "XWimp_CloseDown"                                 ; forget any task we started up
  1071. .reporterror_passon
  1072.   Mov     R14,#0
  1073. f$  Str     R14,[R12,#wk_threaded]
  1074.   LdmFd   R13!,{R0-R7,Pc}^
  1075. iq.addokbutton                                                ; add button marked 'OK' on old error systems, or
  1076. j]  StmFd   R13!,{R0-R2,R14}                                  ; 'Continue' on Risc PC ones.
  1077.   Sub     R13,R13,#16
  1078.   Tst     R0,#1<<8
  1079.   AdrEqL  R2,t_oldok
  1080.   AdrNeL  R2,t_newok
  1081. o(  Ldr     R1,[R12,#wk_messagesblock]
  1082.   Mov     R0,R13
  1083.   Bl      translate
  1084.   AddVs   R13,R13,#16
  1085.   LdmVsFd R13!,{R0-R2,Pc}
  1086.   Bl      addabutton
  1087.   Add     R13,R13,#16
  1088.   LdmVsFd R13!,{R0-R2,Pc}
  1089.   LdmFd   R13!,{R0-R2,Pc}^
  1090. yt.addcancelbutton                                            ; add button marked 'Cancel', or 'Quit' if in a dead
  1091. zQ  StmFd   R13!,{R0-R2,R14}                                  ; nasty situation
  1092.   Sub     R13,R13,#16
  1093.   Tst     R0,#1<<31
  1094.   AdrEqL  R2,t_cancel
  1095.   AdrNeL  R2,t_quit
  1096. (  Ldr     R1,[R12,#wk_messagesblock]
  1097.   Mov     R0,R13
  1098.   Bl      translate
  1099.   AddVs   R13,R13,#16
  1100.   LdmVsFd R13!,{R0-R2,Pc}
  1101.   Bl      addabutton
  1102.   Add     R13,R13,#16
  1103.   LdmVsFd R13!,{R0-R2,Pc}
  1104.   LdmFd   R13!,{R0-R2,Pc}^
  1105. ^.addabutton                                                 ; add button with text from R0
  1106.   StmFd   R13!,{R0-R2,R14}
  1107. *  Ldr     R1,[R12,#wk_numberofbuttons]
  1108. !  Cmp     R1,#numberofbuttons
  1109.   LdmPlFd R13!,{R0-R2,R14}
  1110.   OrrPlS  Pc,R14,#1<<vbit
  1111. %  Add     R1,R1,#icon_firstbutton
  1112.   Bl      seticonstring
  1113.   LdmVsFd R13!,{R0-R2,Pc}
  1114.   Add     R0,R0,#24
  1115. &  Ldr     R2,[R12,#wk_buttonwidth]
  1116.   Cmp     R0,R2
  1117. p  StrGt   R0,[R12,#wk_buttonwidth]                          ; copy string to icon and update width of button
  1118. &  Ldr     R0,[R12,#wk_windowblock]
  1119.   Add     R0,R0,#88
  1120.   Add     R0,R0,R1,Lsl#5
  1121.   Ldr     R1,[R0,#16]
  1122. (  Bic     R1,R1,#1<<iconflag_deleted
  1123. f  Str     R1,[R0,#16]                                       ; undelete icon so this button appears
  1124. *  Ldr     R1,[R12,#wk_numberofbuttons]
  1125.   Add     R1,R1,#1
  1126. *  Str     R1,[R12,#wk_numberofbuttons]
  1127.   LdmFd   R13!,{R0-R2,Pc}^
  1128. u.translate                                                  ; translate is a general-purpose routine to translate
  1129. t  StmFd   R13!,{R0-R1,R3-R6,R14}                            ; a token in R2 in a message block in R1 to a buffer
  1130. q.findloop                                                   ; in R0; on exit, R2 points to the byte after the
  1131. R  Mov     R3,R1                                             ; zero terminator.
  1132.   Mov     R4,R2
  1133. .compareloop
  1134.   LdrB    R5,[R1],#1
  1135.   Teq     R5,#0
  1136. $  LdmEqFd R13!,{R0-R1,R3-R6,R14}
  1137.   OrrEqS  Pc,R14,#1<<vbit
  1138.   Teq     R5,#10
  1139.   BEq     findloop
  1140.   LdrB    R6,[R4],#1
  1141.   Teq     R5,R6
  1142.   BNe     lineloop
  1143.   Teq     R5,#
  1144. ("=")
  1145.   BNe     compareloop
  1146. .copyloop
  1147.   LdrB    R2,[R1],#1
  1148.   Teq     R2,#10
  1149.   TeqNe   R2,#0
  1150.   MovEq   R2,#0
  1151.   StrB    R2,[R0],#1
  1152.   BNe     copyloop
  1153.   Mov     R2,R0
  1154. $  LdmFd   R13!,{R0-R1,R3-R6,Pc}^
  1155. .lineloop
  1156.   LdrB    R5,[R1],#1
  1157.   Teq     R5,#0
  1158. $  LdmEqFd R13!,{R0-R1,R3-R6,R14}
  1159.   OrrEqS  Pc,R14,#1<<vbit
  1160.   Teq     R5,#10
  1161.   BNe     lineloop
  1162.   B       findloop
  1163. s.seticonstring                                              ; copies string R0 to icon R1, and returns width of
  1164. r  Bic     R14,R14,#1<<vbit                                  ; string in OS units (using Wimp_TextOp on OS 3.5)
  1165. r  StmFd   R13!,{R1-R4,R14}                                  ; returns V set if string won't fit indir space or
  1166. \  Ldr     R2,[R12,#wk_windowblock]                          ; on an unexpected SWI error
  1167.   Add     R2,R2,#88
  1168.   Add     R2,R2,R1,Lsl#5
  1169.   Ldr     R1,[R2,#20]
  1170.   Ldr     R3,[R2,#28]
  1171.   Mov     R4,#0
  1172.   Mov     R2,R0
  1173.     .loop
  1174.   SubS    R3,R3,#1
  1175.   LdmMiFd R13!,{R1-R4,R14}
  1176.   LdrB    R14,[R2],#1
  1177.   Teq     R14,#0
  1178.   AddNe   R4,R4,#16
  1179. t  BNe     loop                                              ; find length of new string and moan if it won't fit
  1180.   Mov     R2,R0
  1181.     .loop
  1182.   LdrB    R14,[R2],#1
  1183.   StrB    R14,[R1],#1
  1184.   Teq     R14,#0
  1185. Y  BNe     loop                                              ; copy new string to icon
  1186.   Mov     R3,R0
  1187. *  Mov     R0,#wimp_readsysinfo_wimpver
  1188. !  Swi     "XWimp_ReadSysInfo"
  1189.   LdmVsFd R13!,{R1-R4,Pc}
  1190.   Mov     R14,#350 
  1191. $  Orr     R14,R14,#320 
  1192.  &FF)
  1193.   Cmp     R0,R14
  1194.   MovMi   R0,R4
  1195. v  LdmMiFd R13!,{R1-R4,Pc}^                                  ; on OS <3.5 WIMP, return width as that in system font
  1196. )  Mov     R0,#wimp_textop_stringwidth
  1197.   Mov     R1,R3
  1198.   Mov     R2,#0
  1199.   Swi     XWimp_TextOp
  1200.   LdmVsFd R13!,{R1-R4,Pc}
  1201. n  LdmFd   R13!,{R1-R4,Pc}^                                  ; on OS 3.5 WIMP, ask it how big the string is
  1202. _.geticonwidth                                               ; return width of icon R0 in R0
  1203.   StmFd   R13!,{R1,R14}
  1204. &  Ldr     R1,[R12,#wk_windowblock]
  1205.   Add     R1,R1,#88
  1206.   Add     R1,R1,R0,Lsl#5
  1207.   Ldr     R0,[R1]
  1208.   Ldr     R1,[R1,#8]
  1209.   Sub     R0,R1,R0
  1210.   LdmFd   R13!,{R1,Pc}^
  1211. \.seticonwidth                                               ; set width of icon R0 to R1
  1212.   StmFd   R13!,{R0-R2,R14}
  1213. &  Ldr     R2,[R12,#wk_windowblock]
  1214.   Add     R2,R2,#88
  1215.   Add     R2,R2,R0,Lsl#5
  1216.   Ldr     R0,[R2]
  1217.   Add     R0,R0,R1
  1218.   Str     R0,[R2,#8]
  1219.   LdmFd   R13!,{R0-R2,Pc}^
  1220. _  Equs    
  1221. 10+"You think you're strong. We'll see. Du mu
  1222. t Ambo
  1223.  oder Hammer sein."+
  1224. ?  Equs    "And... anything below here is probably a virus."
  1225.  "OS_File",10,"<Program$Path>ErrorWind",&FFA,,code,O%
  1226.