The RISC OS Desktop provides an ideal environment for using the Archimedes, but tends to get in the way when developing programs. For example, the only way to edit, or even examine, a Basic program is to temporarily leave the Desktop environment. The utility presented here helps to get around this by allowing the quick conversion of a Basic program into its text equivalent and vice versa. The resulting text file can then be edited using Edit.
Start by creating a new directory on disc called B_to_T, and go into this directory. Enter, save, and run listing 1, which will create and save a !Sprites file. Then use Edit to enter the Obey file from listing 2 and save this in the directory with the name !Run. Finally, enter listing 3 and save this in the directory as BConvert.
The converter is installed from the Desktop by double clicking on its icon in the viewer. This will cause the icon to appear on the icon bar. The converter cannot be 'opened' as such - instead, files are dragged onto its icon. To convert a file, drag it onto the icon. After a short delay, a save box will pop up with the converted text file. This can either be saved, or dragged directly into another application. For example, to examine and modify a Basic program, drag its icon onto the converter. Then, drag the resulting text file into Edit. After making any changes, bring up Edit's save box, drag the file back to the converter, and finally save the new Basic version of the file.
To merge two Basic programs, convert the first one and drag it into Edit. Position Edit's text caret on the first blank line after the program listing. Next, convert the second program and drag its text file into the same Edit window. This will cause Edit to append the two text files. However, it is likely that the line numbers will not be correct. To get around this, just delete the line number from the first line. This will force the converter to renumber the program when it is converted back to Basic. Finally, 'save' the file from Edit into the converter, and then save the resulting Basic program which will contain the two original listings appended. Obviously, this can be extended to append any number of programs.
This month's magazine disc contains an enhanced version of the converter which allows a program to be edited outside the Desktop. To do this, hold down Shift while dragging the file onto the converter. Instead of opening a save box, Basic will be entered with the program present. After any changes have been made (possibly using the Basic Editor), press function key F1. This will re-enter the Desktop, and pop up a save box for the modified program. If you don't wish to save it, simply press Return to cancel the box.
10 REM >SpriteMake
20 DIM sp 1000:!sp=1000:sp!4=0
30 sp!8=16:sp!12=16
40 SYS "OS_SpriteOp",271,sp,"!B_to_T",0,34,17,12
50 FOR Y%=0TO16:FOR X%=0TO33
60 SYS "Wimp_SpriteOp",41,,"file_ffb",X%,Y% TO ,,,,,C%
70 IF C%=7 THEN C%=8
80 IF X%>Y%*2 THEN
90 IF C%=0 THEN C%=7
100 IF C%=8 THEN C%=0
110 ENDIF
120 SYS "OS_SpriteOp",298,sp,"!B_to_T",X%,Y%,C%
130 NEXT:NEXT
140 SYS "OS_SpriteOp",268,sp,"!Sprites"
WimpSlot -min 32K -max 32K
IconSprites <Obey$Dir>.!Sprites
Run <Obey$Dir>.BConvert
10 REM >BConvert
20 REM Program Basic Converter
30 REM Version A1.00
40 REM Author David Spencer
50 REM RISC User July/August 1989
60 REM Program Subject to Copyright
70 :
80 DIM block 256,menu 50,oldblk 100
90 P%=block:[OPT 0:STR R14,[R0]
100 MOV PC,R14:]A%=block+20:CALL block
110 match=block!20+72:taddr=match+4
120 PROCun(match):PROCun(taddr)
130 PROCassemble
140 $block="TASK":SYS "Wimp_Initialise",200,!block,"Basic<>Text" TO ,us
150 file=FNwindow:DIM oks 2:$oks="OK"
160 ok=FNicon(file,192,-160,238,-112,&C701913D,oks,0,3)
170 DIM fname 255,valid 3,sprite 20
180 $valid="a~ "
190 name=FNicon(file,10,-160,186,-112,&700F13D,fname,valid,256)
200 ficon=FNicon(file,78,-92,146,-20,&D7006102,sprite,1,20)
210 DIM sprite2 20:$sprite2="!B_to_T"
220 sicon=FNicon(-1,0,0,68,68,&3102,sprite2,1,20)
230 quit=FALSE:myref=-1
240 ON ERROR PROCerror
250 REPEAT
260 SYS "Wimp_Poll",1,block TO reason
270 CASE reason OF
280 WHEN 2:SYS"Wimp_OpenWindow",,block
290 WHEN 6:PROCbuttons(block)
300 WHEN 7:PROCdragdone
310 WHEN 8:PROCkey(block!24)
320 WHEN 9:quit=TRUE
330 WHEN 17,18:PROCreceive(block)
340 WHEN 19:PROCnoack(block)
350 ENDCASE
360 UNTIL quit
370 SYS "Wimp_CloseDown"
380 END
390 :
400 DEF PROCreceive(b)
410 CASE b!16 OF
420 WHEN 0:quit=TRUE
430 WHEN 1:PROCsavetous(b)
440 WHEN 2:PROCdatasave(b)
450 WHEN 3:PROCdataload(b)
460 WHEN 6:PROCramfetch(b)
470 WHEN 7:PROCramtransmit(b)
480 ENDCASE
490 ENDPROC
500 :
510 DEF PROCkey(k)
520 CASE k OF
530 WHEN 13:PROCsaveit($fname)
540 WHEN 27:!block=file:SYS "Wimp_CloseWindow",,block:PROCrelease(cst)
550 OTHERWISE:SYS "Wimp_ProcessKey",k
560 ENDCASE
570 ENDPROC
580 :
590 DEF PROCbuttons(b)
600 IF (b!8 AND 2) THEN
610 IF b!12=-2 PROCmenu(b)
620 ELSE
630 IF b!16=ficon AND (b!8 AND &50)<>0
THEN
640 !b=file
650 SYS "Wimp_GetWindowState",,b
660 wex=b!4-b!20:wey=b!16-b!24
670 b!4=ficon
680 SYS "Wimp_GetIconState",,b
690 !b=file:b!4=5
700 b!8=b!8+wex:b!12=b!12+wey
710 b!16=b!16+wex:b!20=b!20+wey
720 b!24=0:b!28=0
730 b!32=&7FFFFFFF:b!36=&7FFFFFFF
740 SYS "Wimp_DragBox",,b
750 ENDIF
760 IF b!16=ok THEN PROCsaveit($fname)
770 ENDIF
780 ENDPROC
790 :
800 DEF PROCmenu(b)
810 $menu="Basic<>Text"
820 menu!12=&70207:menu!16=156
830 menu!20=40:menu!24=0:menu!28=&80
840 menu!32=-1:menu!36=&7000021
850 $(menu+40)="Quit"
860 SYS "Wimp_CreateMenu",,menu,!b-64,136
870 ENDPROC
880 :
890 DEF FNwindow
900 !block=900:block!4=200
910 block!8=1146:block!12=368
920 block!16=0:block!20=0
930 block!24=-1:block!28=&93
940 block!32=&1070207:block!36=&20D04
950 block!40=0:block!44=-1024
960 block!48=1280:block!52=0
970 block!56=&3D:block!60=0
980 block!64=1:block!68=0
990 block!84=0:$(block+72)="Save as:"
1000 SYS "Wimp_CreateWindow",,block TO handle
1010 =handle
1020 :
1030 DEF FNicon(window,x1,y1,x2,y2,flags,i1,i2,i3)
1040 !block=window:block!4=x1
1050 block!8=y1:block!12=x2
1060 block!16=y2:block!20=flags
1070 block!24=i1:block!28=i2
1080 block!32=i3
1090 SYS "Wimp_CreateIcon",,block TO handle
1100 =handle
1110 :
1120 DEF PROCdragdone
1130 IF totext THEN type=&FFF ELSE type=&FFB
1140 SYS "Wimp_GetPointerInfo",,block
1150 block!20=64:block!32=0
1160 block!36=1:block!40=block!12
1170 block!44=block!16:block!48=!block
1180 block!52=block!4
1190 block!56=end-bst:block!60=type
1200 $(block+64)=FNleaf($fname)+CHR$0
1210 SYS "Wimp_SendMessage",17,block+20,block!12,block!16
1220 myref=block!28:start=bst
1230 ENDPROC
1240 :
1250 DEF FNleaf(path$)
1260 WHILE INSTR(path$,"."):path$=MID$(path$,INSTR(path$,".")+1)
1270 ENDWHILE
1280 =path$
1290 :
1300 DEF PROCerror
1310 SYS "Wimp_DragBox",,-1
1320 !block=ERR:$(block+4)=REPORT$+" (Internal error code "+STR$ERL+")"+CHR$0
1330 SYS "Wimp_ReportError",block,1,"Basic<>Text"
1340 ENDPROC
1350 :
1360 DEF PROCsavetous(b)
1370 totext=(b!40=&FFB)
1380 FOR F%=0 TO 43 STEP 4
1390 oldblk!F%=b!F%:NEXT
1400 b!12=b!8:b!16=6
1410 ff$=FNgname(b+44)
1420 bst=FNclaim(b!36*2)
1430 bend=bst+b!36*2:bst2=bst+b!36
1440 b!20=bst2:b!24=bend-bst2
1450 SYS "Wimp_SendMessage",17,b,b!4
1460 myref=b!8:retry=TRUE:size=0
1470 ENDPROC
1480 :
1490 DEF PROCnoack(b)
1500 IF b!12=myref THEN
1510 IF retry THEN
1520 oldblk!12=oldblk!8:oldblk!16=2
1530 !oldblk=100
1540 $(oldblk+44)="<Wimp$Scrap>"+CHR$0
1550 SYS "Wimp_SendMessage",17,oldblk,oldblk!4
1560 myref=oldblk!8:retry=FALSE
1570 ELSE ERROR 1,"Pipe Broken"
1580 ENDIF
1590 ENDIF
1600 ENDPROC
1610 :
1620 DEF PROCdatasave(b)
1630 IF b!12=myref THEN
1640 PROCsaveit(FNgname(b+44))
1650 b!12=b!8:b!16=3
1660 SYS "Wimp_SendMessage",18,b,b!4
1670 ENDIF
1680 ENDPROC
1690 :
1700 DEF PROCramtransmit(b)
1710 size+=b!24
1720 IF b!24=bend-bst2 THEN
1730 b!12=b!8:b!16=6
1740 SYS "Wimp_SendMessage",18,b,b!4
1750 ELSE end=FNconvert(bst2,size,bst)
1760 PROCpopup
1770 ENDIF
1780 ENDPROC
1790 :
1800 DEF PROCdataload(b)
1810 IF b!40=&FFF OR b!40=&FFB THEN
1820 totext=(b!40=&FFB)
1830 ff$=FNgname(b+44):X%=OPENIN ff$
1840 s%=EXT#X%:CLOSE #X%
1850 bst=FNclaim(s%*2):bend=bst+s%*2
1860 SYS "OS_File",&FF,ff$,bst+s%
1870 end=FNconvert(bst+s%,s%,bst)
1880 PROCpopup
1890 IF b!12=myref THEN *DELETE <Wimp$Scrap>
1900 b!12=b!8:b!16=4
1910 SYS "Wimp_SendMessage",17,b,b!4
1920 ENDIF
1930 ENDPROC
1940 :
1950 DEF PROCramfetch(b)
1960 IF b!24<cnd-start THEN cend=start+b!24 ELSE cend=cnd
1970 SYS "Wimp_TransferBlock",us,start,b!4,b!20,cend-start
1980 b!12=b!8:b!16=7:b!24=cend-start
1990 SYS "Wimp_SendMessage",18,b,b!4
2000 start=cend
2010 IF start=cnd THEN !menu=file:SYS "Wimp_CloseWindow",,menu:PROCrelease(cst)
2020 ENDPROC
2030 :
2040 DEF FNgname(ptr):LOCAL f$
2050 WHILE ?ptr f$+=CHR$?ptr:ptr+=1
2060 ENDWHILE
2070 =f$
2080 :
2090 DEF PROCsaveit(name$)
2100 IF INSTR(name$,".") THEN
2110 IF totext THEN type=&FFF ELSE type=&FFB
2120 SYS "OS_File",10,name$,type,,cst,cnd
2130 PROCrelease(cst):!menu=file
2140 SYS "Wimp_CloseWindow",,menu
2150 ELSE $block=" To save, drag the
icon to a directory viewer"
2160 SYS "Wimp_ReportError",block,1,"Basic<>Text"
2170 ENDIF
2180 ENDPROC
2190 :
2200 DEF PROCpopup
2210 cst=bst:cnd=end:fn$=FNleaf(ff$)
2220 fm$=LEFT$(ff$,LENff$-LENfn$)
2230 IF LENfn$=10 THEN fn$=LEFT$(fn$,9)
2240 IF totext fp$="T" ELSE fp$="B"
2250 $fname=fm$+fn$+fp$:!oldblk=file
2260 IF totext THEN $sprite="file_fff" ELSE $sprite="file_ffb"
2270 SYS "Wimp_GetWindowState",,oldblk
2280 SYS "Wimp_OpenWindow",,oldblk
2290 SYS "Wimp_SetCaretPosition",file,name,,,-1,LEN$fname
2300 ENDPROC
2310 :
2320 DEF FNclaim(size):SYS "OS_Module",6,,,size TO ,,ptr:=ptr
2330 :
2340 DEF PROCrelease(RETURN ptr):IF ptr
THEN SYS "OS_Module",7,,ptr:ptr=0
2350 ENDPROC
2360 :
2370 DEF PROCun(RETURN addr)
2380 addr=addr+8+(!addr AND &FFFFFF)*4
2390 ENDPROC
2400 :
2410 DEF FNconvert(from,len,to)
2420 SYS "Hourglass_On"
2430 IF totext THEN
2440 D%=from+1:E%=to:to=USR code
2450 ELSE
2460 A%=from:B%=from+len:C%=to+1
2470 ?to=13:to=USR tok
2480 ENDIF
2490 SYS "Hourglass_Off"
2500 =to
2510 :
2520 DEF PROCassemble
2530 DIM code 512
2540 FOR pass=0 TO 2 STEP 2
2550 P%=code:[OPT pass
2560 STMFD R13!,{R12,R14}
2570 .l LDRB R1,[R3,#1]
2580 LDRB R0,[R3]:ADD R0,R1,R0,LSL#8
2590 CMP R0,#&FF00:MOVCS R0,R4
2600 LDMCSFD R13!,{R12,PC}^
2610 MOV R1,R4:MOV R2,#6:ADD R3,R3,#3
2620 SWI "OS_ConvertCardinal2"
2630 MOV R4,R1:.l1 LDRB R0,[R3],#1
2640 CMP R0,#13:BEQ ld:CMP R0,#&8D
2650 BEQ ln:CMP R0,#&7F
2660 STRCCB R0,[R4],#1:BCC l1
2670 MOV R12,R3:BL taddr:MOV R3,R12
2680 .l2 LDRB R0,[R1],#1:CMP R0,#&7F
2690 STRCCB R0,[R4],#1:BCC l2:B l1
2700 .ld MOV R0,#10:STRB R0,[R4],#1
2710 B l:.ln LDRB R0,[R3],#1
2720 MOV R2,R0,LSL #2:LDRB R0,[R3],#1
2730 AND R1,R2,#&C0:EOR R0,R0,R1
2740 MOV R5,R0:LDRB R0,[R3],#1
2750 MOV R1,R2,LSL #2:EOR R0,R0,R1
2760 AND R0,R0,#&FF:MOV R2,#6
2770 ORR R0,R5,R0,LSL #8:MOV R1,R4
2780 SWI "OS_ConvertCardinal2"
2790 MOV R4,R1:B l1
2800 .tok STMFD R13!,{R0-R2,R14}
2810 MOV R6,R0:MOV R7,R1:MOV R8,R2
2820 MOV R9,#0:.tl CMP R6,R7
2830 ADDCS R13,R13,#4:MOVCS R0,#&FF
2840 STRCSB R0,[R8],#1:MOVCS R0,R8
2850 LDMCSFD R13!,{R1-R2,PC}
2860 LDRB R0,[R6],#1
2870 CMP R0,#13:CMPNE R0,#10
2880 CMPNE R0,#32:BEQ tl:SUB R1,R6,#1
2890 CMP R0,#&30:BCC nono:CMP R0,#&3A
2900 BCC num:.nono CMP R9,#0
2910 MOVEQ R9,#10:LDMEQFD R13,{R6-R8}
2920 BEQ tl:MOV R2,R9:ADD R9,R9,#10
2930 B num2:.num LDR R2,llim
2940 LDR R0,base:SWI "OS_ReadUnsigned"
2950 CMP R9,#0:BNE nono
2960 .num2
2970 STRB R2,[R8,#1]:MOV R2,R2,LSR #8
2980 STRB R2,[R8]:ADD R2,R8,#3
2990 MOV R3,#0:MOV R4,#0:BL match
3000 MOV R6,R1:SUB R0,R2,R8
3010 STRB R0,[R8,#2]:ADD R8,R8,#3
3020 .elc LDRB R0,[R8],#1:CMP R0,#32
3030 BEQ elc:CMP R0,#&8B:MOVEQ R0,#&CC
3040 STREQB R0,[R8,#-1]:MOV R8,R2:B tl
3050 .base EQUD 10+(1<<29)
3060 .llim EQUD &FEFF:]NEXT
3070 ENDPROC