@C9coding hints and cheats

@C6
A hint for the SWI "Wimp_PollIdle"
@C7
Many Wimpcoder do have the bad manner to call Wimp_Poll with the Reasoncode 0,
to get back the control fastest possibly. In fact they don`t need it in most
cases, they do one or two checks to keep track of the environment and return.
This behaviour takes much polltime, that other tasks would need more urgently.
And because only very few programms really need to be called at every poll pe-
riod, for most of the task being called once a second should be more than enough
so better use the SWI "Wimp_PollIdle" which takes the same entry conditions as
"Wimp_Poll" but also takes in R2 the earliest return time in cs. This depends
on the monotonic system time so if you want to be called after a second, use
the following code:
@C3
 SYS "OS_ReadMonotonicTime"TOA%
 SYS "Wimp_PollIdle",0,Block%,A%+100
@C7
but note, that you must not mask out the Null event as Wimp_PollIdle tries to
call you with that event.

@c1
@C6
BASIC Functions in the BASIC inline assembler
@C7
Inside the BASIC inline assembler it is possible to call defined user functions
without leaving the inline assembler enviroment. You do not even need to deter-
mine a destination for the function. You simply have to write:
@C3
  MOV R0,#123                   ; unimportant asm trash
  EOR R0,R0,R0
  @CBFNmyfunction@C3                  ; call your function!
  MOV PC,R14
@C7
So it is possible to implement your own features for easier assembling. Some
examples are given here:

- reserve workspace
  This function reserves a block of the given byte-size. To do this it incre-
  ments the assembling destination addresses P% and O% by the given amount of
  bytes.
@C3
  DEF FNworkspace(amount%)
    P%+=amount%
    O%+=amount%
  =0
@C7
  example for use:
@C3
  .tempblock FNworkspace(512)   ; reserve 512 bytes for temp data
@c7

- fill an area with bytes
  This function fills an area of the given size with the given byte value.
@C3
  DEF FNfillb(length%,value%) LOCAL I%
    FOR I%=P% TO P%+length%
    ?I%=value%
    NEXT I%
    P%+=length%
  =0
@c7
  But you must not use this version of the function when offset-assembling.
  (Bit 2 of OPT-variable set) In this case the address for storing the values
  is in O% instead of P%. You have to change the function in this way:
@C3
  DEF FNfillb(length%,value%) LOCAL I%
    FOR I%=O% TO O%+length%
    ?I%=value%
    NEXT I%
    P%+=length%
    O%+=length%
  =0
@C7
  example for use:
@C3
  .datalabel FNfillb(1024,0)    ; fill an area of 1024 bytes with 0
@C7

- include external file into the assembling stream
@C3
  DEF FNfile(name$) LOCAL I%
    SYS "OS_File",16,name$,P% TO ,,,,I%
    P%+=I%
  =0
@C7
  As described above you have to use another version of this routine for offset-
  assembling, too:
@C3
  DEF FNfile(name$) LOCAL I%
    SYS "OS_File",16,name$,O% TO ,,,,I%
    P%+=I%:O%+=I%
  =0
@C7
  example for use:
@C3
  .picture FNfile("hotgirl")    ; include raw graphics data...
@C7

- prevent a block of instructions from being assembled
  This set of functions disables the assembling of all code which is enclosed
  by them. This is very usefull for debugging-purposes: If you want to exclude
  a piece of code you do not need to insert a ';' before every single instruc-
  tion. You simply have to write a 'FNremon' before and a 'FNremoff' after the
  section to be excluded.
@C3
  DEF FNremon
    remptr%=P%
  =0

  DEF FNremoff
    O%-=P%-remptr%
    P%-=P%-remptr%
  =0
@C7
  example for use:
@C3
  MOV R0,#&2000000
  FNremon
  STMDB R0!,{R1-R8}             ; exclude this from assembling
  FNremoff
  CMP R0,R9
  BNE blabla@C7

@c1
@C6
About filenames
@C7
Progs that have to deal with files often have the problem the extract the file-
name from the whole pathname, ie. the program only needs the (mostly) 10 letters
of file. A very simple way to do that is shown here:

@C3WHILE INSTR$(File$,".")>0
 File$=MID$(File$,INSTR$(File$,".")+1)
ENDWHILE@C7

@c1
@C6
Loud harddiscs
@C7
Hard discs are really fine things... but some of them start annoying after a
time due to the noises they make. But most ADFS harddiscs offer a spindown SWI.
So you don`t need any of these kilobytessucking applications that do offer to
spin harddiscs down, as the following routine does the same. Simply pin this
file to the pinboard and start it in 'case of emergency'. Replace the xx with
your hard disc`s drive number.

@C3SYS "ADFS_PowerControl",2,xx,0@C7

and the assembler version:

@C3MOV  R0,#2
MOV  R1,#xx
MOV  R2,#0
SWI  "ADFS_PowerControl"
MOV  PC,R14@C7

@c1
@C6
A guide to your sound system
@C7
It`s a mistake to think, the Archimedes sound system was hard to control, with
the following simple routine you may create random sounds, the first creates
oercussion rhytms, the second one adds some melody.

@C3SYS "Sound_Enable",2
SYS "Sound_AttachVoice",1,6
REPEAT
SYS "Sound_Configure",0,0,RND(55)
SYS &100 + 7
FOR I% = 1 TO 8 : SYS "OS_Byte",19 : NEXT
UNTIL 0

SYS "Sound_Enable",2
REPEAT
IF RND(2) =1 THEN SYS "Sound_AttachVoice",1,4 ELSE SYS "Sound_AttachVoice",1,7
SYS "Sound_Configure",0,0,RND(55)
SYS &100 + 7
FOR I% = 1 TO 8 : SYS "OS_Byte",19 : NEXT
UNTIL 0@C7

@c1
@C6
Reading the keyboard
@C7
Most BASIC programmers know and use the INKEY(x) instruction. But most of them
don`t know that you also can check single keys, and if they know they often
don`t know how to use it. If the x is negative, the appropriate key is checked
but not, as you may think, the key which is represented by the ASCII code of -x,
but they use same key format as OS_Byte 121 does. That`s the internal key number
And the x is the bitinverted (NOT) number. A list of these keynumbers you may
find in the extended StrongHelp, but it`s also available in the Bits directory.

@c1
@C6
Caution when using LZW!
@C7
The LZW`s Compress and Decompress SWIs use the Screenmem as temporary buffer.
But LZW only reads the screenbase address when initialised. Therefore, when a
mode change takes place, and the screenmem address increases, the old address
doesn`t isn`t any longer available, ie. it lies outside the mapped in memory,
this has to lead to errors. The only thing you can do is to reinitialise the
module after modechanges and before using it again.

@c1
@C6
FOR NEXT loop cheats
@C7
At end of an FOR NEXT loop usually a 'NEXT' is used, isn`t it? If you use two
nested loops which end succesively, you usually use 'NEXT I%,J%' or so. But like
in a single FOR NEXT loop, you don`t have to specify the loop variables. A sim-
ple @C3NEXT,@C7 is enough.

