4878 lines
153 KiB
Plaintext
4878 lines
153 KiB
Plaintext
SIBO 'C' Software Development Kit
|
||||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Version 2.30
|
|||
|
|
|
|||
|
|
|
|||
|
|
March 1, 1999
|
|||
|
|
|
|||
|
|
|
|||
|
|
(C) Copyright Psion PLC 1990-98
|
|||
|
|
|
|||
|
|
|
|||
|
|
All rights reserved. This manual and the programs referred to herein are copyrighted works of Psion PLC,
|
|||
|
|
London, England. Reproduction in whole or in part, including utilization in machines capable of
|
|||
|
|
reproduction or retrieval, without express written permission of Psion PLC, is prohibited. Reverse
|
|||
|
|
engineering is also prohibited.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The information in this document is subject to change without notice.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Psion and the Psion logo are registered trademarks, and Psion, Psion MC, Psion HC, Psion Series 3, Psion
|
|||
|
|
Series 3a, Psion Series 3c, Psion Siena and Psion Workabout are trademarks of Psion PLC.
|
|||
|
|
|
|||
|
|
|
|||
|
|
TopSpeed is a registered trademark of Clarion Software Corporation. IBM, IBM XT and IBM AT are
|
|||
|
|
registered trademarks of International Business Machines Corp. Microsoft and MS-DOS are registered
|
|||
|
|
trademarks of Microsoft Corporation. Apple and Macintosh are registered trademarks of Apple Computer
|
|||
|
|
Inc. VAX and VMS are registered trademarks of Digital Equipment Corporation. Brief is a registered
|
|||
|
|
trademark of Underware Inc. Psion PLC acknowledges that some other names referred to are registered
|
|||
|
|
trademarks.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Contents
|
|||
|
|
|
|||
|
|
|
|||
|
|
1 Installation .............csccsssssssscssscrssssceeeeseeeseeeseesseesssesseesseesseesseesseesseesseesseesceesceesseescesscsscesoseesoeees 1-1
|
|||
|
|
Installation: :: i328 Assisi Aces whe chad Oks Ahsdoke sneha saniiin 1-1
|
|||
|
|
Dif CtOry StEU Chute css 259s sie, Boost eek os shsg eats tess eth clees da Dies cos thes oT Dees ous hes eb Tset vous Teeneeeaav 1-2
|
|||
|
|
Reconfiguring the TopSpeed project SysteM...........cssessecssseeesneecsseecsseeceseeeesaeessaeers 1-2
|
|||
|
|
Customising the redirection file... eee eeeesesccssneeceneecseecsseecsseeeesseessaeecsaeesssneeessaes 1-3
|
|||
|
|
2 A Brief Overview Of The SIBO SDK...............scsscsssssssssesesssesssessscsssesssessesesssessseessesssesssessoeees 2-1
|
|||
|
|
Mantlal si as tcas crest a tacit a ptiteseder chai abste bei eiea ide ahr ianohii ast 2-1
|
|||
|
|
WHEE TO SCALE sis ont 0k cee sat can abet ech veits es AlN oeuviuat ses alts cavvainases Ud oetitialens Gioia oe 2-2
|
|||
|
|
The terms SIBO and EPOC explained ..........ceeceeceseseecsseessseeceseeeesaeeesaeecsaeeesseeessaes 2-2
|
|||
|
|
Fatal programming errors (Pamics) .........ceseeeseeceseeessceeesseecsseecsaceceeecesaeeesaeesseessneeeeseaeers 2-3
|
|||
|
|
Panic NUMDers :s..s:205 iors hess devas Gales eee eek bigs vaneiens ian Ghee 2-3
|
|||
|
|
C++ and Object Oriented programming ...........eesceeseeceseeceseeesseeseeecseeeseseeeesaeessaeesseeesee 2-3
|
|||
|
|
3 Building An Application ...............csscccssscssssccsscsssscsssssssssscsssecsssecsssssssssssssscnssscsessesssssssesseesees 3-1
|
|||
|
|
INtroduchOti sais cei eh ab de ash kd Heh ah ee lg 3-1
|
|||
|
|
Equipment required: :ctics 2 otesscvsthsce soba. cosa doee nesdussceusonasuestuaccavediseseassysoansibensseussaes 3-1
|
|||
|
|
Whichfilesare needed 2.5. ccsscusi.5 coves cavsciestidebeccheves iol stebeset evveieh Steee sed seveted ees etlvber 3-2
|
|||
|
|
Avfirst: éxample-applCattonicsssi.ci.tsiscssteasactealasieestesisceat le doenteaietenulads. agancdelasieesascaendst 3-2
|
|||
|
|
A first look at projectiles o 525; ccissckeuei Seuscbehsiengotd Seubebetsaesaoch yuh veh sdebaten ouoh evshcgubeoeh Suenee 3-2
|
|||
|
|
Creating: the ime filet:4 iain ohana lan ouB asian lanl 3-3
|
|||
|
|
Copying the program to the target Machine ........ eee eeeeceeneeeeeeceeesseessseeessaeeesaee 3-3
|
|||
|
|
Running the program on the target COMPULET........... ee eeeeeeeeneeeeneeceneeseaeessseeeeteeeesaee 3-3
|
|||
|
|
Stepping through the program with the SIBO Debugger .......... eee eeeeeeseeeeseeeeeeeeenes 3-4
|
|||
|
|
A PEIB version Of Hello Wotldssssis.scccbes.ceadeseseepiessc svda deste hiss apsviebe abtbies aeessarboeeeescbaae 3-4
|
|||
|
|
PEIB- and ‘CLIB conitrasted oi. sc... 205 sicse eves cevetul sees teas caved ub steve neste. fel stevssustevbs felseeseesstyl 3-4
|
|||
|
|
The-code for p hello. i drcssectssvestasscasseaiate adacteostea lareadaadenstestaseendsieasteataceenderioes eters 3-5
|
|||
|
|
The epocinit statement in -pr files... eee eee eeseeesseeceseeesseeeeseeeesaeecsaeesseeesneessnaeeesaes 3-6
|
|||
|
|
Housekeeping batch files and re-using project files... eee eeseeeseeceseeeeeeeeesseeesaeessneeeees 3-6
|
|||
|
|
A general project file: unnamed. pF oe. eee eeeeeeeseeceseeesseesseeceseeeesaeeesaeessaeessseeeesaes 3-6
|
|||
|
|
A batch file for test Compilation .......... eee eeeeeeseeesseecsneeceseeeesaeeesaeecsaeecsaeessneeeeteeeesaes 3-6
|
|||
|
|
SOME COMPLICALLONS. os 2565 55h sete oks Fe heh ios Povk a gheties Soe Sivd ou gh adieba Sen usd bu gb ctuboveu dunk aubetedo tue 3-7
|
|||
|
|
TSE versus ISCX i sssiostiss Mann eatin Aeniisscess teas dapbescrsp bate sapdasecesp hase aspbebs evades vundays 3-8
|
|||
|
|
More complicated programming SeCtUPS ..........:.csscessseceseeceseeeceseeceaeecseecseaeeesaeecsaeessneeeees 3-9
|
|||
|
|
Simple: PEIB: examples. sis.2ccasiasesetasicasagiasventaalateesbaadvestaasatessdawdoestestavesetaaateatagsgers 3-9
|
|||
|
|
Moulti- file: prograinss.i sc castsisiceiiecigasl a sccbehicskpth auhcvelceeheoek Sheicvehjesbepehoigievesdestek sist 3-9
|
|||
|
|
Graphics programs. ::..2.5:4 cp mstdceai Mapas dete Aeiiesicnipiensdapbeadseteti ss dngiescAeetise deeds 3-10
|
|||
|
|
FAWIP progranns csc ossi0s cossccts tours cds Faveeubedevsesdsduyacad edu vse sdsdueaeevsdvetesds svneebsteesecosteensvbanes 3-10
|
|||
|
|
Customised) libraries ¥s.::2)c<.t2s.ss555.92.diabateansaiste ddatpeatacisgeeleahe asibasounlastetestansendastoees 3-10
|
|||
|
|
Applications containing assembler as Well aS Cu... eee eeeeceeseeceseeeesneeseeeesseersaeeseeeeees 3-11
|
|||
|
|
Other advanced use of the project file SySteM..........esceesceeessceeesneeceseeceneeceseeeesaeessaeers 3-11
|
|||
|
|
Greater control over the image file created... eee eeeeeseeesneessneeceeeeceeeesaeeesaeeesaeersneeenee 3-12
|
|||
|
|
Priority, minimum heap, and version NUMDET............: ce eeeeeseesneeeeneeceneeceseeeseeeeneeeesaes 3-12
|
|||
|
|
Use.OF Edumipiex rc. isiiit jf it ievieta Mis nhee Mi Ane oeiicciad sie eaten ile sed 3-12
|
|||
|
|
Differences between .app files and .1mg files 0.0.0... eles eeeeeesneeeeneeceeeceeeeseeeeseeeesaes 3-13
|
|||
|
|
Ad d=file ist si... ess Seeose ed Stbbe ous oP ysis saubease Sevseeesebsdis TeesesbeSas RIP Ivers thus nerve eres 3-13
|
|||
|
|
Changing the set of add-files in an 1Mage......... eee eeeeeeeseeceseeeseecsaeecsseeeeseeeesaeeseaeers 3-14
|
|||
|
|
|
|||
|
|
|
|||
|
|
Further uses of emake.exe ............ccccccceseeseccccccceeessseccccssseeeesseecccsssseueeseescessssueeeseeessess 3-14
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
ii
|
|||
|
|
|
|||
|
|
|
|||
|
|
4 Notes On CLIB.............sccssssssscssscsssesssessserssesssesssesssesseesssssssesssesssesssesssesssesseesssessesseessseessesseeeseees 4-1
|
|||
|
|
Functions missing from the MS-DOS JPIC library... eee eeeeeseeesseeeeseeeeeneeeeneees 4-1
|
|||
|
|
TAS OR 5s deste ces; cass nevedeepavstbs sb eeagbassdact salscesodanpdhugasasevacespdensosbi cusses sosevehes Aantensseeraion tes 4-2
|
|||
|
|
DIVE eset rt MM eR el oa NN oe ah oe te eee area ones ute aa PEG cara eset hs 4-2
|
|||
|
|
File handle conversion routine............ceeseseseecsscecesceesseecseecseecsseeeesaeecsaeessneessseeeesaes 4-2
|
|||
|
|
Phe Console: Channel. 22. cscs ices svadesessahpscossteg egebseey ages ced evebsdes seete dns esehstnpsaubeted oses step pee 4-3
|
|||
|
|
MS-DOS ‘file names’.$3:.; ac.cseiyaieentiaelecnsie aie oui are ei ayia 4-3
|
|||
|
|
Floating point emulator .......... ce eeeeeeeeesseecsscecsseeceseeeesneecsaeecsseeceseecesseecsaeecseessneeeesaes 4-3
|
|||
|
|
Pate 80:s3isni this talest gain dain saad Palas ote Shaina osetia. 4-3
|
|||
|
|
Building the CLIB library and header objects ............eeeeeeseeseseeceseeeeeeeeesseeesaeesseeeees 4-4
|
|||
|
|
Cautionary Notes sssi.c.e i etiavien it ashe aoiaaiei ota bad ieee 4-4
|
|||
|
|
|
|||
|
|
5 Fundamental Programming Guide-lines ................cccssccssssseccsscssecssccecsssccecesseseesssccseesssceseeens 5-1
|
|||
|
|
|
|||
|
|
Tin tr OG UCHIOT os ek tes el iach i at wae cate cal ced ste cand eat see canned aenteat Si steee canta 5-1
|
|||
|
|
Other related docuMeNntatiOn.......... ee eeseeeseecsseecesceeesseecsseecseeceseeeesaeessaeesseeseneeessaes 5-1
|
|||
|
|
The source code for the examples ............eesceesecceseeeeseecseecsceseseeeesaeecsaeesseeesneeeesaes 5-2
|
|||
|
|
User Anterface:. sii 2isi8 thas ets as bee avis lensed Avid dau esi tvico bei esiteda teh 5-2
|
|||
|
|
|
|||
|
|
A first look at multiple event SOUTCES......... cee eeseeeseeesseeeesceceeseeesaeecsaeecsseecseecesaeeesaeecsaeers 5-3
|
|||
|
|
Remarks ‘On timers -.$:5. silts. oiel oo he Bled ea aed hie Band hao eetied 5-4
|
|||
|
|
Remarks: on ke ypresses's:J.c5:33 sasiesidecvtsteAisiasihas beth Naidesddtedevid aioe dei Aenea ha 5-4
|
|||
|
|
MO re Oi p1OWalt iss cos2o os sats Syceubsteus sab cdian cos vssisa Ans cous Avtsiba Aig eevadoreubs Ran eeiidawbonvs daads 5-4
|
|||
|
|
Status words: the other side Of P_lOWa€It oo... eee eeeeeeseeceseeceseeeeseecseecseeseseeeesaeessaeers 5-5
|
|||
|
|
Prioritisation Of CVENt SOULCES ........ eee eesecsseeesseeceseeeesseecsseecsseeceeeeesaeecsaeerseeesteeeesaes 5-5
|
|||
|
|
VO devices ii ceneralicss, ateissi assess cast eA sisesiostsse Sh ssaveisndeesbesed stestoseepoasivaeensseeressi ha 5-5
|
|||
|
|
The Console: device seccs2.es2.5 vege cuss sivedes Soves cuts Sesiel sake cavsebbesea savage cals cevaded Seats seitenusden Sinbely 5-6
|
|||
|
|
How to‘Canicel::a thers ch sisiss-stssiacdticeassstacdeeledesetaatageetds tess eataosendadeasteaiagendaieaetens 5-6
|
|||
|
|
Where to declare status WOrdS..........ccceescccseseessseecseecsneecsseecssaesesaeecsaeessaeeseeeessaeeesaes 5-7
|
|||
|
|
|
|||
|
|
A-first,look at ertorharidling 3: ).35c cenit dail endri ees eed e Baste 5-7
|
|||
|
|
Brror handling in Events cin: coiscsess.basi.5 cats toons tsdhah eeisduose 0s bi bevadeesecus ds nsvetevsrDuteseiee 5-7
|
|||
|
|
Fatal errors and non-fatal errors ..........eeeceeeseesseeesseecssceceececesaeeesaeecsaeessaeesseesssaeeesaes 5-8
|
|||
|
|
When resources need to be tidied explicitly... eeeccesneeesneeesneeseseeseseeeesaeessaeers 5-8
|
|||
|
|
|
|||
|
|
Inter-Process Communication: Events2 and Subproc.........eeeeeeeseesseeeeseeceseeeeseeeesaeeesaeers 5-8
|
|||
|
|
Acthird €vetit SOULCE ws c.65cistescd0s seuss eckeeebtee, Fei stvbs foibteestes stvie feb Tebslen sins Pevtdewsta ste de 5-8
|
|||
|
|
How Events2 passes data to SUDPI0C........ eee eeseeeeseeeeseeceseeeesaeeesaeecsaeecsaeessneesesaeeesaes 5-9
|
|||
|
|
The Code ti SUBProcis css sot cass cvs ssies Sab Lobe ewek Sheu pied Pedbewss Subd Lock Setacw es Seeeuoeh ocoenweh Sesooeh Senne 5-10
|
|||
|
|
Mechanisms for inter-process COMMUNICATION .......... eee eeeeeeseeeseeeeeeeeseeeeaeessaeesseeeees 5-10
|
|||
|
|
Debugging cooperating applications ........... cee eeeseecsseeeeseeeesseeesseecsaeecseecsseeeesaeeesaeers 5-11
|
|||
|
|
Error Handling im Bvents2.5:.235 hss stds hcenkictessedealetentigiagsotesisceeidatsosanaaieasieatiaesneanenyiass 5-11
|
|||
|
|
Socially responsible programming in Events2............:ecceesseeesseeeeseecsececeeeeeseeeeseeeesaes 5-11
|
|||
|
|
|
|||
|
|
Data received from:a-serial port s.s.s.5:.5 sts eiades his dacien aes eathisl asin An 5-11
|
|||
|
|
Opening the:serial: Port cssis: yess ochisek saves cash cieised Stees eavlevesselstese cas ieves ced sesesw eevee aeeei ss 5-12
|
|||
|
|
Active and inactive CVeNt SOUTCES 20... eeseeesseceseeeeseeeseeeesaeecsaeecsacecsseecseeeseeesnaeeesaes 5-12
|
|||
|
|
Debugging applications with serial COMMS ............:esecesseceeseeeeseeeseecsneeeeseeeesaeessaeers 5-13
|
|||
|
|
The tole:of: ptickles 2:8 wise aA inde iitha dade asada tshadea aes 5-13
|
|||
|
|
|
|||
|
|
Yielding CPU in compute-intensive programs ...........ssccseseeceseeceseceseeeeseeessaeecsaeessereeeenes 5-13
|
|||
|
|
Tdl@:ObjecCtss. 2: ssesisscsscaseesteaissectagusaasd ataceas deters ncaisenndaseadeenesaat daha Moeetes etenhda Goeetdaa st cat 5-14
|
|||
|
|
The meaning of calling p_1osignal......... ees eeeeeseecesneeeseeseeeesaeeceacecseeceseesseeseseeeesaes 5-14
|
|||
|
|
One drawback of COMtiINUOUS ACtIVILY ...... eee eee eeeeeeeseeceeeeseeeesaeeceaeecsseecetersneeeenaeeesaes 5-14
|
|||
|
|
Remarks On process PriOrities ........ ee eeseeeseecsseeeesceeesseecsaeecseeceseecesaeeesaeesseeesneeeesaes 5-14
|
|||
|
|
The-call p-tOvyieldissisiss. sdasscessashassadaseteatastasiostatess tan caseendateestentassenda seasteaiaveendateastgas 5-14
|
|||
|
|
|
|||
|
|
Gremeral Perm ark o.ii61. 255s scis sh nahh a oest iocs disk Bevdeed Se ckbvad pes cbeesied hisheoui se sheteh el ouboe sereh erent oe 5-16
|
|||
|
|
Multi-threadedness and multi-tasking... eee eeeesseeeseeeeseeeeseeeesseeseeeesaeessaeesseeeees 5-16
|
|||
|
|
Subprocess or 1dlé: Object? «1.5. isseeestais bi steviesevich eistest tc ata aeons bees 5-16
|
|||
|
|
Window redraws as an Vent SOUTCE....... ee eeesenecesneessneeseseeceseecsseecesaeessaecesseeesneeeesaes 5-16
|
|||
|
|
The APPMAN and ACTIVE classes in OLIB .0......ceseeeeceessecesseeceneecseeeeeseeeesaeessaeers 5-16
|
|||
|
|
|
|||
|
|
|
|||
|
|
CONTENTS
|
|||
|
|
|
|||
|
|
|
|||
|
|
6 Copy-Protecting Softwar e...............scsscssccssscssssscssesssscscecssscesssscssesssscsssssscsscsssscssesssscssssssceseees On
|
|||
|
|
|
|||
|
|
|
|||
|
|
Tin tO Ct Oni aps fos oe dees teg shoes eiestene tee stcga estes See sata ig stes ott slong esac seep tene eset deestene eats 6-1
|
|||
|
|
The freespace method s:.icisieiia ph eit ia. pei banning es 6-1
|
|||
|
|
First generation copying methods......... ec eeeeeseesscesssceesseecesseeesaeecsaeecseecsseecesaeeesaeeesaeers 6-2
|
|||
|
|
Preserving checksums :..3...2.:rvidiene aie kieran eh al nna eie 6-2
|
|||
|
|
What kind of change should be made «0.0.00... eeeeeeeeesseeeeseessnceceseeeesaeecsaeessaeesseeeesas 6-2
|
|||
|
|
Restricting the number of copies Made .......... ees eeseeeseeeeseceesseeesseecsseecsneeceseeeesaeessaeers 6-3
|
|||
|
|
Low level SSD information’, « o::.06. 22st. he oes eho hk ee oe dhe eel ae eh ad ae 6-3
|
|||
|
|
Copy-protection by changing the ROM 00.0... eescessecsseecsseeceseeeesaeeesaeecsaeecesaeeesaeessaeers 6-3
|
|||
|
|
|
|||
|
|
|
|||
|
|
7 Compatibility: sccsscssccccsscsecccssssescestcsnsacsesssaassssssssssosvensseseveasdsocvansdsdevansdsentancsesssadessnosesessosnstesueseeg dL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Initroduct On ¢::::.43. nA kee ius Lis Anh Aoh lhe Mon koh aah aae 7-1
|
|||
|
|
What machine am I running ON? ............ceeecceeessceceeseceeesseneecessaseecessneecensaneesessnsesessnsesenses 7-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
iii
|
|||
|
|
|
|||
|
|
|
|||
|
|
CHAPTER 1
|
|||
|
|
|
|||
|
|
|
|||
|
|
INSTALLATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
The Psion SIBO 'C' Software Development Kit (SDK) enables you to develop applications in 'C' for the
|
|||
|
|
Psion SIBO family of hand-held and notebook computers:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the HC range of corporate handheld computers
|
|||
|
|
e the Series3 range of palmtop computers
|
|||
|
|
e the MC range of laptop mobile computers.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The SDK is PC based - that is, you write and build your applications on a IBM PC or compatible and then
|
|||
|
|
run (or debug) the application on a SIBO computer.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The SIBO SDK comes in three variants: Professional (Prof), Standard (Std), and Documentation (Doc).
|
|||
|
|
The Prof and Std variants contain differing amounts of the TopSpeed C Package (produced by the Clarion
|
|||
|
|
Software Corporation):
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the Prof variant contains the complete TopSpeed C Package
|
|||
|
|
e the Std variant omits the TechKit and C Library Source Kit portions of the TopSpeed C Package.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Parts of the TopSpeed C Package are required in order to build any SIBO application. These are the parts
|
|||
|
|
included in the Std variant of the SDK.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The TopSpeed C Package may be used independently of the SDK to write C programs to run on IBM PCs
|
|||
|
|
and compatibles.
|
|||
|
|
|
|||
|
|
|
|||
|
|
All three variants of the SDK contain the same three volumes of SDK documentation, comprising 14
|
|||
|
|
different manuals all told, together with associated software produced by Psion. This software
|
|||
|
|
incorporates libraries, header files, auxiliary programming tools, example programs, and much more
|
|||
|
|
besides.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Installation
|
|||
|
|
|
|||
|
|
There are three phases to installing the SIBO SDK:
|
|||
|
|
e installing the small code model of the TopSpeed C Package
|
|||
|
|
e installing Psion software and example programs
|
|||
|
|
¢ customising the TopSpeed system using special Psion files.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For information on installing the TopSpeed system, see the TopSpeed C documentation. (You may install
|
|||
|
|
other code models as well as the small code model, but they will not be used by the SIBO SDK).
|
|||
|
|
|
|||
|
|
|
|||
|
|
The Psion software consists of required parts and optional parts. For a full description of all the
|
|||
|
|
available files, see the read.me files in the root directories on the supplied disks.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The files on the disks are in compressed ("zipped") form. The disks contain the pkzunzip program, which
|
|||
|
|
can be used to decompress ("unzip") the other files as they are copied.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The installation procedure ensures that each group of files is copied to its correct directory. The read.me
|
|||
|
|
files on the disks specify which files are present in each group.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Directory structure
|
|||
|
|
The TopSpeed software is usually located in a \fs\ directory tree.
|
|||
|
|
The Sibosdk software is usually located in a \sibosdk\ directory tree.
|
|||
|
|
|
|||
|
|
|
|||
|
|
There is no need for the \rs\ and \sibosdk\ directory trees to be on the same partition of your hard disk. Eg
|
|||
|
|
the TopSpeed system could be on drive c:, with the Sibosdk system on drive d:.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Both the \ts\sys and \sibosdk\sys directories should be added to the MS-DOS path. Alternatively, you may
|
|||
|
|
copy the contents of \sibosdk\sys (with the probable exception of the ts.red redirection file - see
|
|||
|
|
Customising the redirection file below) to \ts\sys, in which case you will only need to add the \rs\sys
|
|||
|
|
directory to the MS-DOS path.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Subdirectories under \sibosdk\ include:
|
|||
|
|
|
|||
|
|
|
|||
|
|
lib the location of standard libraries, startup objects, and some loadable device drivers
|
|||
|
|
(dynamic extensions to the SIBO operating system)
|
|||
|
|
|
|||
|
|
|
|||
|
|
include the location of header files
|
|||
|
|
|
|||
|
|
sys the location of the SIBO Debugger and other miscellaneous programming tools
|
|||
|
|
|
|||
|
|
pr the location of some standard project files
|
|||
|
|
|
|||
|
|
demo the location of various standard demo programs
|
|||
|
|
|
|||
|
|
s3atool Series 3a versions of an icon editor and the Spy application
|
|||
|
|
|
|||
|
|
STC (not present in all versions) the location of the source code for the Clib (standard C)
|
|||
|
|
library
|
|||
|
|
|
|||
|
|
|
|||
|
|
hwdemo (optionally) the location of programs demonstrating use of the HWIF library
|
|||
|
|
|
|||
|
|
|
|||
|
|
hwifsre (optionally) the entire, buildable, source of the HWIF library, for interest and/or to allow
|
|||
|
|
the writing of extensions to HWIF
|
|||
|
|
|
|||
|
|
wd (optionally) the source printer scripts of some WDR printer driver files
|
|||
|
|
|
|||
|
|
Idd (optionally) the source code of some example device devices
|
|||
|
|
|
|||
|
|
hemast (optionally) software allowing alternative versions of the HC rom to be built
|
|||
|
|
|
|||
|
|
wkdemo (optionally) source code of example software for the Workabout
|
|||
|
|
|
|||
|
|
fconv (optionally) software allowing the creation of file format conversion DYLs for Word
|
|||
|
|
|
|||
|
|
|
|||
|
|
oopdemo (optionally) the location of programs demonstrating the basic use of the Object Oriented
|
|||
|
|
Programming system (other directories contain more advanced examples)
|
|||
|
|
|
|||
|
|
|
|||
|
|
record (optionally) the source of the Object Oriented Series 3a Record application. This is
|
|||
|
|
buildable, provided that the \sibosdk\oop directory has also been installed
|
|||
|
|
|
|||
|
|
|
|||
|
|
The SIBO SDK requires between 3 and 6 Megabytes of disk space, depending on how much of it is
|
|||
|
|
installed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Reconfiguring the TopSpeed project system
|
|||
|
|
|
|||
|
|
|
|||
|
|
The Sibosdk software contains files, including tsprj.txt and tsmain.txt, that are replacements for files of
|
|||
|
|
the same name released by TopSpeed. The Sibosdk versions of the files allow the TopSpeed project system
|
|||
|
|
to handle the Epoc 1Mc system type, and the Sibosdk tools generally, in addition to the systems normally
|
|||
|
|
supported by TopSpeed. (See the following chapter for more details.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
The Sibosdk versions should be copied, from \sibosdk\sys, over the TopSpeed versions in \ts\sys (as guided
|
|||
|
|
by read.me). Copies of the original TopSpeed files should be kept, with their extensions changed to .old
|
|||
|
|
|
|||
|
|
|
|||
|
|
(say).
|
|||
|
|
|
|||
|
|
|
|||
|
|
In case any specialised changes have already been applied to, say, your tsprj.txt and tsmain.txt files, you
|
|||
|
|
should re-apply these changes to the Sibosdk versions.
|
|||
|
|
|
|||
|
|
|
|||
|
|
1 INSTALLATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
In order for all these changes to have any effect, the TopSpeed tool tscfg has to be run:
|
|||
|
|
type cd \ts\sys to enter the appropriate directory
|
|||
|
|
type tscfg to invoke tscfg.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that the replacement files are not the same as those supplied with versions of the SDK earlier than
|
|||
|
|
2.0. You must therefore repeat the reconfiguration process, even if you are upgrading from a previous
|
|||
|
|
SDK version.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Customising the redirection file
|
|||
|
|
|
|||
|
|
|
|||
|
|
The \sibosdk\sys directory contains the redirection file ts.red that allows the TopSpeed project system to
|
|||
|
|
find the SIBO SDK header files, library files, and other required files. When you invoke the project
|
|||
|
|
system to build an Epoc application it must be able to find this file. If there is no such file in the current
|
|||
|
|
directory, the TopSpeed system looks for this file in the directory containing the TopSpeed software itself
|
|||
|
|
(usually \ts\sys). So there are two options:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e overwrite the TopSpeed ts.red file (in the \ts\sys directory) with the Psion ts.red file (in the
|
|||
|
|
\sibosdk\sys directory), and place a copy of the original TopSpeed ts.red file into the directory in
|
|||
|
|
which you are writing PC C applications (if any)
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ copy the Psion ts.red file into the directory in which you are writing a SIBO application.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The first option is more appropriate if you are writing more SIBO applications than PC applications, the
|
|||
|
|
second if you are not.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The contents of the default ts.red file is basically as listed below. Again, note that the supplied file is
|
|||
|
|
different from the ts.red in earlier versions of the SDK.
|
|||
|
|
|
|||
|
|
|
|||
|
|
*.PR = .; C:\SIBOSDK\PR;
|
|||
|
|
|
|||
|
|
* 7H = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
*,HPP = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
*,RH = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
ta = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
*.RG = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
*.XG = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
*.RSG = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
* INC = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
ee = .; C:\SIBOSDK\SRC;
|
|||
|
|
*.CPP = .; C:\SIBOSDK\SRC;
|
|||
|
|
*.CAT = .; C:\SIBOSDK\SRC;
|
|||
|
|
|
|||
|
|
*.A = .; C:\SIBOSDK\SRC;
|
|||
|
|
*.,OBJ = .; C:\SIBOSDK\LIB;
|
|||
|
|
|
|||
|
|
* LIB = .; C:\SIBOSDK\LIB;
|
|||
|
|
|
|||
|
|
* HLP = C:\TS\DOC;
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, the meaning of the line
|
|||
|
|
*.H = .; C:\SIBOSDK\INCLUDE;
|
|||
|
|
|
|||
|
|
|
|||
|
|
is that any .h file referenced in the course of building an application should be searched for first in the
|
|||
|
|
current directory, then in the c.\sibosdk\include directory.
|
|||
|
|
|
|||
|
|
|
|||
|
|
To increase the search path for .h files, so that private .h files can be located from some other directory,
|
|||
|
|
just edit the ts.red file so that the line becomes, for example:
|
|||
|
|
|
|||
|
|
|
|||
|
|
baa! = .; ..\INCLUDE; C:\SIBOSDK\INCLUDE
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that the contents of this file assume that you have installed the Sibosdk system on your c: drive. If
|
|||
|
|
you have installed it on another drive you will have to edit ts.red to refer to the appropriate drive.
|
|||
|
|
|
|||
|
|
|
|||
|
|
1-3
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
1-4
|
|||
|
|
|
|||
|
|
|
|||
|
|
CHAPTER 2
|
|||
|
|
|
|||
|
|
|
|||
|
|
A BRIEF OVERVIEW OF THE SIBO SDK
|
|||
|
|
|
|||
|
|
|
|||
|
|
The SIBO SDK consists of a set of floppy disks containing the SDK software and a number of manuals
|
|||
|
|
describing the software and the Psion SIBO family of mobile and hand-held computers. The floppy disks
|
|||
|
|
contain the various tools, header files, libraries etc that are required to produce an image (img) file that
|
|||
|
|
will run on Psion SIBO machines.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Manuals
|
|||
|
|
|
|||
|
|
|
|||
|
|
The SDK manuals supplement the TopSpeed manuals. In particular you are referred to the TopSpeed C
|
|||
|
|
Library reference for the description of standard C (CLIB) library functions.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The SDK contains the following manuals:
|
|||
|
|
|
|||
|
|
|
|||
|
|
General Programming Manual
|
|||
|
|
|
|||
|
|
|
|||
|
|
HC Programming Guide
|
|||
|
|
|
|||
|
|
|
|||
|
|
Series 3/3a Programming Guide
|
|||
|
|
|
|||
|
|
|
|||
|
|
Workabout Programming Guide
|
|||
|
|
|
|||
|
|
|
|||
|
|
EPOC OSS System Services
|
|||
|
|
|
|||
|
|
|
|||
|
|
Additional System Information
|
|||
|
|
|
|||
|
|
|
|||
|
|
PLIB Reference
|
|||
|
|
|
|||
|
|
|
|||
|
|
Window Server Reference
|
|||
|
|
|
|||
|
|
|
|||
|
|
I/O Devices Reference
|
|||
|
|
|
|||
|
|
|
|||
|
|
The SIBO Debugger
|
|||
|
|
|
|||
|
|
|
|||
|
|
Hardware Reference
|
|||
|
|
|
|||
|
|
|
|||
|
|
Programming in HWIF
|
|||
|
|
|
|||
|
|
|
|||
|
|
This manual. It describes how to install the SDK, and how to
|
|||
|
|
build an application that will run on the SIBO machines. It also
|
|||
|
|
contains some notes on using the TopSpeed C Library reference
|
|||
|
|
manual, some discussion on how to copy protect software for
|
|||
|
|
SIBO computers, and a potentially very important chapter entitled
|
|||
|
|
Fundamental Programming Guidelines.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Some documentation particularly oriented around the HC
|
|||
|
|
computer range.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Some documentation particularly oriented around the Series 3
|
|||
|
|
range of machines.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Some documentation particularly oriented around the Workabout
|
|||
|
|
computer.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Describes the software interrupt interface to the ROM-based
|
|||
|
|
system services. An appendix contains a complete listing of the
|
|||
|
|
EPOC service numbers. This will be of particular use to OPL and
|
|||
|
|
assembly language programmers who wish to make direct access
|
|||
|
|
to EPOC services.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Describes the MCLink communications software, resource files,
|
|||
|
|
WDR printing, various file formats, how to write device drivers,
|
|||
|
|
and other miscellaneous topics.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Describes the Psion PLIB library (this library provides the most
|
|||
|
|
direct access to the ROM based system services).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Describes the window server library WLIB which implements a
|
|||
|
|
range of sophisticated graphics operations.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Describes the interface to some of the Epoc device drivers,
|
|||
|
|
including those which access the serial and parallel ports.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Describes how to use the SIBO Debugger to debug applications
|
|||
|
|
being developed for SIBO computers.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Describes the basic hardware of SIBO computers.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Describes the HWIF library (which contains support - mainly for
|
|||
|
|
the Series3 - for menus, dialogs, editors, and printing).
|
|||
|
|
|
|||
|
|
|
|||
|
|
2-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Object Oriented Programming Describes the development of applications using Object Oriented
|
|||
|
|
|
|||
|
|
Guide techniques. Its introduction provides an overview of Psion's
|
|||
|
|
Object Oriented programming system and of the OLIB, HWIM,
|
|||
|
|
FORM and XADD object libraries.
|
|||
|
|
|
|||
|
|
|
|||
|
|
ISAM Reference Describes the ISAM dynamic library which provides Indexed
|
|||
|
|
Sequential Access management for large database files.
|
|||
|
|
|
|||
|
|
OLIB Reference Describes the OLIB object library.
|
|||
|
|
|
|||
|
|
FORM Reference Describes the FORM object library.
|
|||
|
|
|
|||
|
|
HWIM Reference Describes the HWIM object library.
|
|||
|
|
|
|||
|
|
XADD Reference Describes the XADD object library.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Where to start
|
|||
|
|
|
|||
|
|
|
|||
|
|
There is a very large amount of information in these manuals - perhaps too much for any one person to
|
|||
|
|
keep it all in their head. However, few developers will need to make detailed reference to more than
|
|||
|
|
around half of the manuals.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The manuals contain many cross references to sections where various topics are discussed in more detail.
|
|||
|
|
Use these cross references to help you find your way around the SDK documentation. The chapter
|
|||
|
|
immediately after this one is probably the best place to start. Alternatively, start reading the HC
|
|||
|
|
Programming Guide, the Series 3/3a Programming Guide, the Object Oriented Programming Guide, the
|
|||
|
|
Plib Reference manual - or anything that catches your eye as you flick through the pages.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The terms SIBO and EPOC explained
|
|||
|
|
|
|||
|
|
|
|||
|
|
A SIBO machine is a battery-powered portable computer that is based on the SIBO architecture. This
|
|||
|
|
architecture is designed to minimise the size, weight and power consumption of the computer. The key
|
|||
|
|
components of the architecture are:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e A sophisticated power management system that selectively powers subsystems under software
|
|||
|
|
control
|
|||
|
|
|
|||
|
|
|
|||
|
|
e Solid State Disks (SSDs) that provide fast low-power silicon-based mass storage with no moving
|
|||
|
|
parts
|
|||
|
|
|
|||
|
|
|
|||
|
|
e Asynchronous serial interface for peripherals running at high speed (Mega bit rates)
|
|||
|
|
e An 8086 class of processor (or any compatible processor such as an 80286)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e Hardware protection of the system from aberrant processes (address trapping of out-of-range
|
|||
|
|
writes and a watch-dog timer on interrupts being disabled)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e = Real-time clock
|
|||
|
|
|
|||
|
|
e ROM-resident system software
|
|||
|
|
|
|||
|
|
e Graphics LCD display
|
|||
|
|
|
|||
|
|
e A touch sensitive digitising pad that provides a pointing device (used in some models)
|
|||
|
|
e ISDN combo sound system (used in some models).
|
|||
|
|
|
|||
|
|
|
|||
|
|
The hardware architecture is primarily implemented in custom ICs called ASICs. The SIBO architecture
|
|||
|
|
uses surface-mounted static CMOS ICs throughout. For further information see the Hardware Reference
|
|||
|
|
manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The EPOC operating system, designed for the SIBO architecture, has the following features:
|
|||
|
|
e preemptive multi-tasking
|
|||
|
|
e MS-DOS-compatible file systems
|
|||
|
|
e installable file systems, including remote file access
|
|||
|
|
e asynchronous services
|
|||
|
|
|
|||
|
|
|
|||
|
|
e support for client-server architectures (used to implement system components such as the file
|
|||
|
|
server and window server)
|
|||
|
|
|
|||
|
|
|
|||
|
|
2 A BRIEF OVERVIEW OF THE SIBO SDK
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ acomprehensive I/O system with many built-in I/O devices
|
|||
|
|
|
|||
|
|
e dynamically loadable device drivers
|
|||
|
|
|
|||
|
|
e reentrant function library
|
|||
|
|
|
|||
|
|
e multiple processes of the same program share a single copy of the code
|
|||
|
|
e support for object-oriented programming
|
|||
|
|
|
|||
|
|
e code-shared dynamic link libraries.
|
|||
|
|
|
|||
|
|
|
|||
|
|
On SIBO machines, the system software resides on an in-built ROM. A version of the EPOC operating
|
|||
|
|
system also runs on a PC.
|
|||
|
|
|
|||
|
|
|
|||
|
|
See the Plib Reference manual for more details.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Fatal programming errors (Panics)
|
|||
|
|
|
|||
|
|
|
|||
|
|
When the system detects a condition that it believes could only arise from a bug in a the application
|
|||
|
|
program, the system terminates the process with a "panic number" in the range 0 to 255 inclusive (where
|
|||
|
|
the system is said to "panic the process"). A panic is a fatal exception that causes the process to terminate
|
|||
|
|
immediately. There is no way for applications to avoid being terminated when a panic has been started.
|
|||
|
|
|
|||
|
|
|
|||
|
|
As well as protecting the system from defective applications, the panic system enforces a greater discipline
|
|||
|
|
on application code by terminating a process as soon as the condition is detected.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Panic numbers
|
|||
|
|
|
|||
|
|
|
|||
|
|
Programming errors detected within different areas of the system code give rise to different panic
|
|||
|
|
numbers. The following table lists the possible panic numbers and the corresponding system code that can
|
|||
|
|
give rise to them.
|
|||
|
|
|
|||
|
|
|
|||
|
|
0 to 80, and 255 The PLIB library
|
|||
|
|
81 to 129 The Window Server library
|
|||
|
|
130 to 160 The OLIB object library
|
|||
|
|
These panic numbers are described in more detail in the appropriate manuals.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Panic numbers in the range 160 to 254 are used by code that is not resident in the ROM (such as the
|
|||
|
|
ISAM library). A given panic number may be used by more than one piece of code; such a panic may
|
|||
|
|
therefore have one of a number of causes. The only definitive way to discover the origin of such a panic is
|
|||
|
|
to make use of the SIBO Debugger to catch the panic and then trace it back to its source.
|
|||
|
|
|
|||
|
|
|
|||
|
|
C++ and Object Oriented programming
|
|||
|
|
|
|||
|
|
|
|||
|
|
This version of the SDK is compatible with TopSpeed C++ although, at the time of writing, the TopSpeed
|
|||
|
|
C++ package is not supplied by Psion as part of any variant of the SDK.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that the kinds of classes, and the means of creating and accessing them, in C++ are quite different
|
|||
|
|
from those in the Psion Object Oriented programming system.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Regardless of whether you use C or C++ to develop Object Oriented applications, if you wish to use Psion
|
|||
|
|
objects you must create instances of them and send messages to them by the mechanisms that are
|
|||
|
|
described in the Object Oriented Programming chapter of the PLIB Reference manual and the Object
|
|||
|
|
Oriented Programming Guide.
|
|||
|
|
|
|||
|
|
|
|||
|
|
If you intend to develop a SIBO application that uses only Psion objects, you may still use C++ as a
|
|||
|
|
"better" version of C, without making use of its Object Oriented aspects.
|
|||
|
|
|
|||
|
|
|
|||
|
|
You may, if you wish, use a mix of Psion and C++ classes, provided you make sure that you create and use
|
|||
|
|
instances of classes of each kind by the appropriate means. It is quite acceptable, for example, to use Psion
|
|||
|
|
classes for the application manager and user interface, but use C++ classes in the 'engine’ of an
|
|||
|
|
application.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
2-4
|
|||
|
|
|
|||
|
|
|
|||
|
|
CHAPTER 3
|
|||
|
|
|
|||
|
|
|
|||
|
|
BUILDING AN APPLICATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
Introduction
|
|||
|
|
|
|||
|
|
|
|||
|
|
The end result of developing a program to run on a SIBO computer is normally an image program, with
|
|||
|
|
characteristic extension .img. Essentially, .img files are to Epoc what .exe files are to MS-DOS.
|
|||
|
|
(Sometimes, the image file is given the extension .app instead. See later for the distinction between .img
|
|||
|
|
and .app forms of images.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
Image files are actually produced via an intermediary .exe file by the operation of a tool emake.exe,
|
|||
|
|
though in practice this process is automated on behalf of the developer. The point is that the development
|
|||
|
|
cycle for .img files is basically the same as for .exe files in more traditional programming environments.
|
|||
|
|
The same compile-link-debug cycle exists in both cases.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The program is written, compiled, and linked on the PC. These steps involve the TopSpeed compiler and
|
|||
|
|
linker, and TopSpeed project (.pr) files. These steps may also involve the full TopSpeed ts development
|
|||
|
|
environment, which is an Integrated Development Environment (IDE). Alternatively, developers may
|
|||
|
|
prefer a more traditional approach, involving their own favoured stand-alone text editor, and a batch-file
|
|||
|
|
mechanism for invoking the TopSpeed compiler and linker.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Once linked, the program is transferred to the SIBO computer in one of three ways:
|
|||
|
|
e under the control of the SIBO Debugger
|
|||
|
|
e via a SSD written to by a PC SSD drive and then placed into the SIBO computer
|
|||
|
|
e via a serial link, using Comms software such as MCLink.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A program running on a SIBO computer (though not one in its rom) can be debugged under the control of
|
|||
|
|
the SIBO Debugger running on a PC. If the program has been built under special conditions, source level
|
|||
|
|
debugging will be available; otherwise just machine-code level debugging.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The remainder of this chapter gives more details on all the above points:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e it introduces some particularly relevant aspects of the TopSpeed project file system
|
|||
|
|
e it describes some batch files that may be found useful when building applications
|
|||
|
|
|
|||
|
|
|
|||
|
|
e several example applications demonstrate the points made (all the example applications and
|
|||
|
|
associated files referred to in this chapter are optionally copied into \sibosdk\demo when the SDK
|
|||
|
|
is installed)
|
|||
|
|
|
|||
|
|
|
|||
|
|
Equipment required
|
|||
|
|
The following equipment is required in order to create an application that runs on a SIBO computer:
|
|||
|
|
e One target SIBO computer (HC, MC, or Series3)
|
|||
|
|
e One PC
|
|||
|
|
e The TopSpeed C development system on the PC
|
|||
|
|
e The Psion SIBO SDK software on the PC
|
|||
|
|
|
|||
|
|
|
|||
|
|
e One or other form of communication between the HC and the PC.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Around 5 to 7 Mbytes of PC hard disk is required to install the TopSpeed C development system and the
|
|||
|
|
Psion SIBO SDK software. There is no particular requirement for the PC to have extended memory.
|
|||
|
|
Development can take place on an XT, but a 486 machine with around 4 Mbytes of extended memory
|
|||
|
|
machine will obviously produce results more quickly.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Which files are needed
|
|||
|
|
To build an application, the following files are required:
|
|||
|
|
e source files, such as .c and .h files
|
|||
|
|
e aproject file, with extension .pr
|
|||
|
|
e aredirection file, with name ts.red
|
|||
|
|
e libraries, with extension .lib.
|
|||
|
|
At the same time, various batch files (extension .bat) may be found useful.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Additional files may be required for the development of applications with the aid of the Object Oriented
|
|||
|
|
system - see the Object Oriented Programming Guide for further details.
|
|||
|
|
|
|||
|
|
|
|||
|
|
There is no need to have a separate project file or redirection file for every single application. For
|
|||
|
|
example, ordinarily there will only be one redirection file on any one PC, shared between all applications
|
|||
|
|
written on that PC. One possible exception is in the case of developers who use the TopSpeed system to
|
|||
|
|
write PC programs as well as SIBO programs.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A first example application
|
|||
|
|
|
|||
|
|
|
|||
|
|
The following discussion centres around a very simple "Hello World" program.
|
|||
|
|
The source C code is as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
HELLO.C
|
|||
|
|
|
|||
|
|
|
|||
|
|
CLIB Hello World application
|
|||
|
|
bai A
|
|||
|
|
|
|||
|
|
|
|||
|
|
#include <stdio.h>
|
|||
|
|
|
|||
|
|
|
|||
|
|
int main(VOID)
|
|||
|
|
{
|
|||
|
|
printf ("Hello World");
|
|||
|
|
getchar();
|
|||
|
|
return (0);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
Evidently, the program prints the message Hello World onto the screen, waits for the ENTER key to be
|
|||
|
|
pressed, and then terminates.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A first look at project files
|
|||
|
|
|
|||
|
|
|
|||
|
|
Before hello.c can be compiled and linked, a project file needs to be specified. In this case, the following
|
|||
|
|
(hello.pr) suffices:
|
|||
|
|
|
|||
|
|
|
|||
|
|
#system epoc img
|
|||
|
|
#model small jpi
|
|||
|
|
|
|||
|
|
|
|||
|
|
#compile hello
|
|||
|
|
#link hello
|
|||
|
|
|
|||
|
|
|
|||
|
|
The meanings of the last two lines of this file are obvious enough: the file hello.c should be compiled, and
|
|||
|
|
then the resultant object file linked to create hello.img. Note that in any case of ambiguity, the extension .c
|
|||
|
|
should be added to the name specified in the #compile statement.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-2
|
|||
|
|
|
|||
|
|
|
|||
|
|
3 BUILDING AN APPLICATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
The first two lines in hello.pr are less obvious. Their meanings are as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
#system epoc img The end outcome of the build is a .img file, as defined in the Epoc-customised
|
|||
|
|
part of the TopSpeed configuration (alternative #systems include dos and win)
|
|||
|
|
|
|||
|
|
|
|||
|
|
#model small jpi The code is to be compiled in small model (code and data segments each
|
|||
|
|
restricted to 64K), with the jpi (TopSpeed C) convention of using registers to
|
|||
|
|
pass parameters to subroutines.
|
|||
|
|
|
|||
|
|
|
|||
|
|
These two lines must be present in all project files used to build applications for SIBO computers.
|
|||
|
|
Other possible contents of .pr project files are discussed later in this chapter.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Creating the .img file
|
|||
|
|
|
|||
|
|
|
|||
|
|
There are two ways a .pr file can be used to create a .img program:
|
|||
|
|
e inside the TopSpeed ts programming environment (see TopSpeed documentation for full details)
|
|||
|
|
¢ outside the ts environment.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, one reason for working outside the ts environment would be to allow the use of another text
|
|||
|
|
editor, such as Brief.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The remainder of this programming manual describes use of .pr files outside of the ts environment.
|
|||
|
|
For the moment, simply type:
|
|||
|
|
|
|||
|
|
tsc /m hello
|
|||
|
|
to have hello.c compiled and linked, with the end result (among other files) being hello.img.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The significance of the /m parameter is that the project file is executed in "make" mode, with files not
|
|||
|
|
being recompiled or relinked needlessly.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Copying the program to the target machine
|
|||
|
|
|
|||
|
|
|
|||
|
|
If your PC has a set of SSD drives attached, simply copy hello.img onto an SSD in one of these drives,
|
|||
|
|
and then insert the SSD into the target machine (the SIBO computer). Otherwise, you may wish to use
|
|||
|
|
MCLink as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ connect the SIBO computer to your PC using a suitable cable
|
|||
|
|
|
|||
|
|
|
|||
|
|
e run the Link application on the target machine (type 1ink at the HC command line, click on the
|
|||
|
|
Link icon on an MC, or set Remote Link on in the System Screen of a Series3)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e run MCLink on the PC (eg by typing mcurnx if \sibosdk\sys is on your path)
|
|||
|
|
e adjust the MCLink serial port and baud rate parameters if required
|
|||
|
|
|
|||
|
|
|
|||
|
|
e type copy hello.img rem::m:\hello.img to transfer the program to the m: drive of the remote
|
|||
|
|
machine (or copy the file to rem: :m:\img\hello.img on a Series3)
|
|||
|
|
|
|||
|
|
|
|||
|
|
For more details about the MCLink program, see the chapter Mclink, Mcprint, and Slink in the Additional
|
|||
|
|
System Information manual. (For example, that chapter explains how the whole process of running
|
|||
|
|
MCLink can be handled via time-saving batch files at the PC end of the connection.) Finally, another
|
|||
|
|
way the program can be transferred from the PC to the target computer is by using the SIBO Debugger, as
|
|||
|
|
discussed below.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Running the program on the target computer
|
|||
|
|
|
|||
|
|
|
|||
|
|
The way the program is run on the target computer varies from computer to computer:
|
|||
|
|
e onan HC, simply type hello at the s prompt of the Command Shell
|
|||
|
|
e onan MC, use the Run menu command of the System application, and select hello.img
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ ona Series 3 or Series 3a, the entry Hello will appear in the file list of the RunImg application
|
|||
|
|
when this list is next updated (assuming that hello.img has been copied into a \img\ top-level
|
|||
|
|
directory), so that hello.img can be run simply by positioning the highlight over Hello and
|
|||
|
|
pressing ENTER.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-3
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Stepping through the program with the SIBO Debugger
|
|||
|
|
In order to debug a program, there is no special need to copy it "by hand" onto the target machine.
|
|||
|
|
Just type
|
|||
|
|
|
|||
|
|
\sibosdk\sys\sdbg hello
|
|||
|
|
|
|||
|
|
|
|||
|
|
(or equivalent) at the PC end, and ensure Link is running on the target computer. (These instructions
|
|||
|
|
assume that hello.img is in the current directory on the PC.) In due course, the debugging screen will
|
|||
|
|
appear on the PC. (When debugging a program running on an MC, the baud rate for the Debugger to use
|
|||
|
|
may have to be given explicitly - eg \sibosdk\sys\sdbg -b19200 hello.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
Step through the program (use F8 or ALT+S) until it hangs (waiting for a key to be pressed on the target
|
|||
|
|
computer). Or simply run the program to completion (use F9 or ALT+R).
|
|||
|
|
|
|||
|
|
|
|||
|
|
In fact, if hello.img has been built as specified above, the debugging screen will come up in machine code
|
|||
|
|
level. In order to debug at the source code level, a slight change has to be made in the way hello.img is
|
|||
|
|
built:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e = either a line #pragma debug (vid=>full) has to be inserted in the project file (before any
|
|||
|
|
instruction to #compile)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e alternatively, a parameter /v2 can be added to the command line invoking the project file.
|
|||
|
|
Thus typing
|
|||
|
|
|
|||
|
|
tsc /m hello /v2
|
|||
|
|
at the PC command line builds a version of hello.img suitable for source level debugging.
|
|||
|
|
As before, just type
|
|||
|
|
|
|||
|
|
\sibosdk\sys\sdbg hello
|
|||
|
|
|
|||
|
|
|
|||
|
|
but this time, the debugging screen by default starts in source level mode, and supports inspection of
|
|||
|
|
variables, etc. See the SIBO Debugger manual for more details.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A PLIB version of Hello World
|
|||
|
|
|
|||
|
|
|
|||
|
|
PLIB and CLIB contrasted
|
|||
|
|
The above "Hello World" program uses the so-called CLIB library.
|
|||
|
|
|
|||
|
|
|
|||
|
|
CLIB is a version of the TopSpeed C library for the EPOC operating system. As such, it is a version of the
|
|||
|
|
standard ANSI C library. The functions in CLIB are described in the TopSpeed C Library Reference
|
|||
|
|
manual. Additional notes, including a list of the TopSpeed C library functions that are not implemented,
|
|||
|
|
may be found in the following chapter, Notes on Clib.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The EPOC version of the TopSpeed C library supports the ANSI functions and most of the portable
|
|||
|
|
functions that are commonly supported by MS-DOS C libraries such as Microsoft C and Borland's Turbo
|
|||
|
|
C. The less portable functions such as those that access the BIOS and graphics functions are not included.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The benefits of using CLIB are:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e portability (existing C programs can easily be converted)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e less to learn for programmers already familiar with standard C libraries.
|
|||
|
|
|
|||
|
|
|
|||
|
|
However, for many programs, developers are strongly urged to consider using not CLIB but PLIB - Psion's
|
|||
|
|
proprietary C library. Whilst PLIB differs from the ANSI standard in many places, there are good reasons
|
|||
|
|
for all these differences, so as to best take advantage of the Epoc architecture. In particular:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e many of the ROM-based EPOC system services are not available from CLIB (eg asynchronous
|
|||
|
|
I/O, inter-process messaging, the window server graphics functions)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e executables are larger in CLIB and the process takes a larger data segment.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The executables are larger because, although CLIB uses the ROM-based system services wherever
|
|||
|
|
possible, it is still a much "thicker" library than PLIB. The data segments also tend to be larger because
|
|||
|
|
the various CLIB subsystems typically require large static buffers and tables.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-4
|
|||
|
|
|
|||
|
|
|
|||
|
|
3 BUILDING AN APPLICATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
See the Introduction chapter of the PLIB Reference manual for more details.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In fact, unless you are using the in-built user interface object dynamic libraries (accessed using object-
|
|||
|
|
oriented programming), you can freely mix PLIB calls with CLIB. Experienced C programmers can, if
|
|||
|
|
they wish, initially use the more familiar CLIB functions and regard PLIB and WLIB (the window server
|
|||
|
|
library) as they would regard non-portable components of any C library.
|
|||
|
|
|
|||
|
|
|
|||
|
|
It is worth converting completely to PLIB and WLIB when the desirability of making efficient use of
|
|||
|
|
memory outweighs the benefits of portability and familiarity.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The code for p_hello.c
|
|||
|
|
|
|||
|
|
|
|||
|
|
The code for a PLIB version of the above program hello.c is contained in the file p_hello.c:
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
P_HELLO.C
|
|||
|
|
|
|||
|
|
|
|||
|
|
PLIB Hello World application
|
|||
|
|
ef
|
|||
|
|
|
|||
|
|
|
|||
|
|
#include <plib.h>
|
|||
|
|
|
|||
|
|
|
|||
|
|
GLDEF_C INT main(VOID)
|
|||
|
|
{
|
|||
|
|
p_printf ("Hello World");
|
|||
|
|
p_getch();
|
|||
|
|
return (0);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
and a corresponding project file p_hello.pr would be
|
|||
|
|
|
|||
|
|
|
|||
|
|
#system epoc img
|
|||
|
|
#set epocinit=iplib
|
|||
|
|
#model small jpi
|
|||
|
|
|
|||
|
|
|
|||
|
|
#compile p_hello
|
|||
|
|
#link p_hello
|
|||
|
|
|
|||
|
|
|
|||
|
|
The following differences will be noticed between hello and p_hello:
|
|||
|
|
e the PLIB program uses a Psion-proprietary header file (plib.h in this case)
|
|||
|
|
e the PLIB program uses Psion-proprietary function calls (p_xxx functions)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the PLIB program links with a different library (this is one effect of the epocinit line in the
|
|||
|
|
project file - discussed further below).
|
|||
|
|
|
|||
|
|
|
|||
|
|
To build p_hello.img, just type either tsc /m p_hello Of tsc /m p_hello /v2 (the latter producing a
|
|||
|
|
version supporting source-code debugging).
|
|||
|
|
|
|||
|
|
|
|||
|
|
As a result of the differences between hello and p_hello, a substantially smaller .img file is produced (try it
|
|||
|
|
and see).
|
|||
|
|
|
|||
|
|
|
|||
|
|
The reason for the remarkable codesize improvement of the PLIB program is that, as mentioned earlier,
|
|||
|
|
the functions in the PLIB library provide only very thin shells over functionality that is present in the
|
|||
|
|
ROM of the SIBO computer. PLIB programs make better use of the SIBO ROM software than do CLIB
|
|||
|
|
programs. Being tailored to the particular needs of SIBO computers, PLIB evolved with very different
|
|||
|
|
constraints and objectives from standard C libraries. In many cases, PLIB functions can be claimed to
|
|||
|
|
"improve" upon the specification of their nearest CLIB equivalents.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The difference in size between CLIB and PLIB programs is not always so remarkable as in the above
|
|||
|
|
example - it depends on the number and types of library function calls made. Indeed, it is perfectly
|
|||
|
|
possible to write some parts of an application using CLIB, and others in PLIB. This fact considerably
|
|||
|
|
simplifies any process of converting a previous large programming project from one computer system to
|
|||
|
|
the SIBO SDK system.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Whilst it is possible to avoid PLIB entirely, this is not recommended. Time spent gaining familiarity with
|
|||
|
|
the functions in the PLIB library should prove an excellent investment, aiding the production of leaner
|
|||
|
|
and more powerful applications. In any case, familiarity with PLIB is a pre-requisite for accessing many
|
|||
|
|
other parts of the SIBO ROM software - such as the enhanced graphics facilities of the Window Server.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-5
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
The epocinit statement in .pr files
|
|||
|
|
In p_hello.pr, the command
|
|||
|
|
#set epocinit=iplib
|
|||
|
|
|
|||
|
|
|
|||
|
|
sets the value of the project macro %epocinit. Note that this command must precede the #mode1 command
|
|||
|
|
in any .pr file.
|
|||
|
|
|
|||
|
|
|
|||
|
|
This command serves two purposes: it specifies whether you are using the CLIB or PLIB startup object
|
|||
|
|
files, and it specifies the stack size for the .img file produced. The allowed values of sepocinit are:
|
|||
|
|
|
|||
|
|
|
|||
|
|
iclib CLIB startup, 8k stack (recommended size when using CLIB startup)
|
|||
|
|
iclib4 CLIB startup, 4k stack
|
|||
|
|
iclib2 CLIB startup, 2k stack
|
|||
|
|
iplib PLIB startup, 4k stack (recommended size when using PLIB startup)
|
|||
|
|
iplib8 PLIB startup, 8k stack
|
|||
|
|
iplib2 PLIB startup, 2k stack
|
|||
|
|
|
|||
|
|
|
|||
|
|
If sepocinit is not set then it defaults to iclib (as in hello.pr).
|
|||
|
|
|
|||
|
|
|
|||
|
|
You must use the CLIB startup object files if you are writing a program that includes any CLIB library I/O
|
|||
|
|
functions. It is, however, possible to use many CLIB library functions (for example, the memory allocation
|
|||
|
|
functions) in conjunction with the PLIB startup. If you do not use any CLIB library functions then you
|
|||
|
|
should always use the PLIB startup.
|
|||
|
|
|
|||
|
|
|
|||
|
|
See the Introduction chapter in the PLIB Reference manual for more about startup object files.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Housekeeping batch files and re-using project files
|
|||
|
|
|
|||
|
|
|
|||
|
|
A general project file: unnamed.pr
|
|||
|
|
|
|||
|
|
|
|||
|
|
Clearly, a project file such as p_hello.pr can be used, with only nominal changes, for a wide range of other
|
|||
|
|
similar programs.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Consider the related project file, unnamed.pr:
|
|||
|
|
|
|||
|
|
|
|||
|
|
#system epoc img
|
|||
|
|
#set epocinit=iplib
|
|||
|
|
#model small jpi
|
|||
|
|
#compile %main
|
|||
|
|
#link %Smain
|
|||
|
|
|
|||
|
|
|
|||
|
|
in which the only difference from p_hello.pr is that references to p_hello have changed into main.
|
|||
|
|
Any batch file that invokes unnamed.pr has to set the value of smain as a parameter to tsc. For example,
|
|||
|
|
|
|||
|
|
|
|||
|
|
tsc /m unnamed.pr /smain=%1
|
|||
|
|
|
|||
|
|
|
|||
|
|
with the TopSpeed /s construct being used to set the value of main to the variable passed into the batch
|
|||
|
|
file.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A batch file for test compilation
|
|||
|
|
|
|||
|
|
|
|||
|
|
A programmers’ text editor usually has some means to compile or "test compile" a source file, from inside
|
|||
|
|
the editor. Many programmers find this a considerable boost to productivity.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, Brief supports compilation on the ALT-F10 hot key, with the way the compilation is done
|
|||
|
|
being determined by an MS-DOS environment variable:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e = during autoexec.bat (or a batch file called therein), set the value of bcc, eg to !"cc.bat %s"
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the effect of ALT-F10 while editing a .c file would then be to run the batch file cc.bat, passing the
|
|||
|
|
basic name of the file (ie less the path and extension) into the batch file
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the leading exclamation mark specifies that compiler warnings should be reported, as well as
|
|||
|
|
errors.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-6
|
|||
|
|
|
|||
|
|
|
|||
|
|
3 BUILDING AN APPLICATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
The TopSpeed ts integrated development environment naturally possesses an equivalent mechanism, but
|
|||
|
|
some users may prefer to use an independent text editor.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Accordingly, one suggestion is that there should be a file cc.bat in the local directory (or in the path), with
|
|||
|
|
the following contents (or equivalent):
|
|||
|
|
|
|||
|
|
|
|||
|
|
tsc %1.c /fpunnamed
|
|||
|
|
|
|||
|
|
|
|||
|
|
The meaning of the /fp construct is that the specified project file should be used (in this case,
|
|||
|
|
unnamed.pr).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Given that there is no /m in this command (nor any /1), the specified project file is invoked in so-called
|
|||
|
|
"compile" mode: nominated files are compiled, without any files being linked. Further, the compilation
|
|||
|
|
always takes place, without any calculation of whether an object file is already "up-to-date".
|
|||
|
|
|
|||
|
|
|
|||
|
|
Once all the required C source files in a project have been successfully compiled, the programmer can exit
|
|||
|
|
the editor, and then "make" the project in the normal way:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e no time will be wasted in recompiling files unnecessarily
|
|||
|
|
e a.img file will be produced (if the make is successful).
|
|||
|
|
|
|||
|
|
|
|||
|
|
The cc. bat file used for test compilation could be accompanied by a make.bat file that invokes the project
|
|||
|
|
file in "make" mode.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Some complications
|
|||
|
|
|
|||
|
|
|
|||
|
|
There are a couple of shortcomings with the above batch file cc. bat:
|
|||
|
|
e it takes no account of whether files should be compiled with full debug information
|
|||
|
|
¢ it takes no account of a possible specialised .pr file: the project file unnamed.pr is hard-wired.
|
|||
|
|
|
|||
|
|
|
|||
|
|
It does not take too much imagination to come up with a more general scheme - as is embodied in the
|
|||
|
|
batch files cc.bat and make.bat actually shipped with the demo files p_hello.c etc:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e atest should be made for the existence of a project file with name 31. pr
|
|||
|
|
|
|||
|
|
|
|||
|
|
e attention should be paid to the value of an environment variable for whether to generate full
|
|||
|
|
debugging information.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The batch files supplied assume that the required debug status is stored in an environment variable
|
|||
|
|
%4pivids. This should have one of the values v2 (for full debug information) or vo (for no debug
|
|||
|
|
information). However, cc.bat and make.bat each call a subsidiary batch file, checkvid.bat, which ensures
|
|||
|
|
that %jpivias does indeed exist and has one of these values.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The value of s jpivids is itself expected to be set up by calling the final batch file in the suite: vid.bat.
|
|||
|
|
Typing
|
|||
|
|
|
|||
|
|
|
|||
|
|
vid on
|
|||
|
|
at the MS-DOS command line has the effect of setting sjpivids to v2, whereas typing
|
|||
|
|
vid off
|
|||
|
|
|
|||
|
|
|
|||
|
|
sets $jpivids to vo. Typing via by itself echoes the current vid setting.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-7
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
The contents of these four batch files are as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
(vid.bat)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@echo off
|
|||
|
|
|
|||
|
|
goto X%1X
|
|||
|
|
|
|||
|
|
:Xv0X
|
|||
|
|
|
|||
|
|
:Xoff£X
|
|||
|
|
|
|||
|
|
set jpivid=v0
|
|||
|
|
echo VID is now OFF
|
|||
|
|
goto :end
|
|||
|
|
|
|||
|
|
:Xv2X
|
|||
|
|
|
|||
|
|
:XonX
|
|||
|
|
|
|||
|
|
set jpivid=v2
|
|||
|
|
echo VID is now ON
|
|||
|
|
goto :end
|
|||
|
|
|
|||
|
|
2XX
|
|||
|
|
|
|||
|
|
call checkvid
|
|||
|
|
goto Sjpivid%
|
|||
|
|
:v0
|
|||
|
|
|
|||
|
|
echo VID is OFF
|
|||
|
|
goto end
|
|||
|
|
|
|||
|
|
:v2
|
|||
|
|
|
|||
|
|
echo VID is ON
|
|||
|
|
send
|
|||
|
|
|
|||
|
|
|
|||
|
|
(checkvid.bat)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@if not "Sjpivids"=="v2" set jpivid=v0
|
|||
|
|
(co batt)
|
|||
|
|
@echo off
|
|||
|
|
|
|||
|
|
|
|||
|
|
call checkvid
|
|||
|
|
|
|||
|
|
if exist %1.pr goto custom
|
|||
|
|
tsc %1.c /fpunnamed /%jpivids
|
|||
|
|
goto end
|
|||
|
|
|
|||
|
|
:custom
|
|||
|
|
|
|||
|
|
tsc %l.c /fp%1 /%jpivids
|
|||
|
|
|
|||
|
|
send
|
|||
|
|
|
|||
|
|
|
|||
|
|
(make.bat:)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@echo off
|
|||
|
|
|
|||
|
|
call checkvid
|
|||
|
|
|
|||
|
|
if exist %1.pr goto custom
|
|||
|
|
|
|||
|
|
tsc /m unnamed.pr /smain=%1 /%jpivid%
|
|||
|
|
|
|||
|
|
|
|||
|
|
goto end
|
|||
|
|
|
|||
|
|
:custom
|
|||
|
|
|
|||
|
|
tse /m %1.pr /smain=%1 /%jpivid%
|
|||
|
|
send
|
|||
|
|
|
|||
|
|
|
|||
|
|
Naturally, there is considerable scope for further personalisation and enhancement of these batch files, if
|
|||
|
|
desired.
|
|||
|
|
|
|||
|
|
|
|||
|
|
One final refinement would be to use the MS-DOS prompt command to change the prompt to reflect the
|
|||
|
|
current value of vid. For example,
|
|||
|
|
|
|||
|
|
|
|||
|
|
prompt $p_%jpivid%s$sg
|
|||
|
|
|
|||
|
|
|
|||
|
|
(The reason it is generally important to keep track of whether full debugging information is being
|
|||
|
|
generated is that significantly larger .img programs can result in this case.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
TSC versus TSCX
|
|||
|
|
|
|||
|
|
|
|||
|
|
All the examples of compiling and linking that have been given so far use the TopSpeed tsc command.
|
|||
|
|
This command does not make use of expanded memory and may cause problems, particularly when
|
|||
|
|
linking large applications.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Most of the batch files supplied with the SDK to compile, link or make executables use the tsc version. If
|
|||
|
|
this causes difficulties on your PC, you may find that replacing tsc with tscx (which uses expanded
|
|||
|
|
memory) in these batch files will cure the problem.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-8
|
|||
|
|
|
|||
|
|
|
|||
|
|
3 BUILDING AN APPLICATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
More complicated programming setups
|
|||
|
|
|
|||
|
|
|
|||
|
|
The remainder of this chapter makes no mention of programming technique or programming concepts
|
|||
|
|
within the SIBO SDK system (see the later chapter Fundamental Programming Guidelines for that).
|
|||
|
|
Rather, it continues to explain more details of the mechanics of building applications of various sorts.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Simple PLIB examples
|
|||
|
|
|
|||
|
|
|
|||
|
|
The following four programs all use the default project file, unnamed.pr, and each consist of only one
|
|||
|
|
source module:
|
|||
|
|
|
|||
|
|
|
|||
|
|
p_search searches a specified text file for a given piece of text
|
|||
|
|
p_prndir prints specified directory listings to the screen
|
|||
|
|
|
|||
|
|
p_dlist lists all current "devices" (ie local and remote disk drives)
|
|||
|
|
Pp_comp compares two specified files, to see if they match.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, to build a version of p_dlist.img suitable for source-level debugging, just type
|
|||
|
|
|
|||
|
|
|
|||
|
|
vid on
|
|||
|
|
make p_dlist
|
|||
|
|
|
|||
|
|
|
|||
|
|
To exit any of these programs which repeatedly request user input, simply press ENTER on an empty
|
|||
|
|
input line.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note: these programs are all restricted to so-called console i/o:
|
|||
|
|
e no attractive graphics
|
|||
|
|
e limited support for the user editing data entered previously.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Additionally, they pay no attention to the actual size of the screen on individual SIBO computers. Whilst
|
|||
|
|
the data they display fits well enough on the large screen of MC computers, the display is less suited to the
|
|||
|
|
smaller screens of HC or Series3 computers. Simple modifications can make amends in this last regard.
|
|||
|
|
But for enhanced graphics output, use of Window Server functions is needed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Finally, these programs are all single-threaded, ie each has only one event source (the keyboard). At the
|
|||
|
|
same time, they contain no asynchronous i/o. (The vital topics of multi-threaded programming and
|
|||
|
|
asynchronous i/o are two of the central themes of the chapter Fundamental Programming Guidelines.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
But despite their limitations, these four programs will hopefully be found useful for the purpose of
|
|||
|
|
acquiring familiarity with .pr project files and with the SIBO SDK system generally. There is no need to
|
|||
|
|
worry unduly over their detailed content; however, taking the time to build them and then improve them
|
|||
|
|
could well turn out a very rewarding exercise (eg in making the transition from CLIB to PLIB).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Multi-file programs
|
|||
|
|
For a program with more than one source file, the corresponding .pr needs but a slight modification.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, suppose a program triple has three source files: triple.c itself, utils].c and utils2.c. A
|
|||
|
|
suitable project file triple.pr would be
|
|||
|
|
|
|||
|
|
|
|||
|
|
system epoc img
|
|||
|
|
set epocinit=iplib
|
|||
|
|
model small jpi
|
|||
|
|
|
|||
|
|
|
|||
|
|
compile triple
|
|||
|
|
compile utils1l
|
|||
|
|
compile utils2
|
|||
|
|
|
|||
|
|
|
|||
|
|
link triple
|
|||
|
|
The effect of the final #1ink statement is actually as follows:
|
|||
|
|
e link together all the files listed with #compile statements
|
|||
|
|
|
|||
|
|
|
|||
|
|
e link also the relevant startup module and standard libraries
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-9
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
e link also any object files or libraries specified by any #pragma link statements (see below for
|
|||
|
|
examples)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e give the final executable the name specified in the #1ink statement.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note in particular there is no need for the name specified by the #1ink statement to match the name of the
|
|||
|
|
.pr file, nor the name of any of the individual files linked together.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Graphics programs
|
|||
|
|
|
|||
|
|
|
|||
|
|
Programs which interact directly with the Window Server can produce a large variety of impressive
|
|||
|
|
graphics effects - icons and bitmaps, shapes and areas, mixed fonts and styles, scrolling and animation,
|
|||
|
|
information messages and alerts, and so on.
|
|||
|
|
|
|||
|
|
|
|||
|
|
These programs can operate with .pr files of exactly the same form as described earlier in this chapter. For
|
|||
|
|
example, the file unnamed.pr can continue to be used, unchanged, for any simple single-module Window
|
|||
|
|
Server program. Parts of the Window Server library, wlib.lib, are automatically linked in as required,
|
|||
|
|
without any change being required in the .pr file: there is no need to ask for wlib.lib explicitly.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The source modules will, of course, have to change in the following aspects:
|
|||
|
|
e calls to Window Server functions gxxx or wxxx will be included
|
|||
|
|
e the Window Server header file wlib.h will have to be #included.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For more details, including some introductory Window Server programs of the "Hello World" variety, see
|
|||
|
|
the Window Server Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
HWIF programs
|
|||
|
|
|
|||
|
|
|
|||
|
|
Developers writing for the Series3 can take advantage of the additional menu and dialog functionality
|
|||
|
|
(amongst other features) of the HWIF library, to create applications very similar to those built into the rom
|
|||
|
|
of the Series3.
|
|||
|
|
|
|||
|
|
|
|||
|
|
See the Programming in HWIF manual for full details, including a suite of example programs.
|
|||
|
|
Project files for these programs need to include the line
|
|||
|
|
|
|||
|
|
#pragma link (hwif.lib)
|
|||
|
|
since the HWIF library is not one of those that are automatically searched at link time.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Customised libraries
|
|||
|
|
|
|||
|
|
|
|||
|
|
Developers may wish to collect various utility routines, or other subsets of code, into their own libraries,
|
|||
|
|
which can in due course be linked into different programs. Possibly, developers may wish to distribute
|
|||
|
|
their libraries in object form (./ib files), and not in source form. In such a case, there is likely to be at least
|
|||
|
|
two different .pr files: one controlling the creation of the .lib file, and one that, later, joins the ./ib file into
|
|||
|
|
a required application program.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, suppose that modules utils/.c and utils2.c are to be compiled and linked into a library called
|
|||
|
|
utils.lib. This can be accomplished by means of the following project file:
|
|||
|
|
|
|||
|
|
|
|||
|
|
#system epoc img
|
|||
|
|
#set epocinit=iplib
|
|||
|
|
#model small jpi
|
|||
|
|
#compile utilsl
|
|||
|
|
#compile utils2
|
|||
|
|
#dolink utils.lib
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note the following points:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the command #dolink is used rather than #1ink, to stop the TopSpeed system attempting to link
|
|||
|
|
in a startup object too (not to mention other standard libraries)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the extension .1ib explicitly given overrides the default .img that would otherwise be assumed
|
|||
|
|
on account of the statement #system epoc img.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-10
|
|||
|
|
|
|||
|
|
|
|||
|
|
3 BUILDING AN APPLICATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
A project file to produce an application tutils, say, that made use of functionality in utils.lib, could then be
|
|||
|
|
as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
#system epoc img
|
|||
|
|
|
|||
|
|
#set epocinit=iplib
|
|||
|
|
#model small jpi
|
|||
|
|
#compile tutils
|
|||
|
|
#pragma link (utils.1lib)
|
|||
|
|
#link tutils
|
|||
|
|
|
|||
|
|
|
|||
|
|
with utils.lib being searched for along the path specified in the redirection file ts.red.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Applications containing assembler as well as C
|
|||
|
|
|
|||
|
|
|
|||
|
|
In principle, it is perfectly possible for an application to include assembler source modules, as well as
|
|||
|
|
modules written in C.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, if an application contains two source files, cfile.c written in C and afile.a written in
|
|||
|
|
assembler, the following could appear in the project file:
|
|||
|
|
|
|||
|
|
|
|||
|
|
#compile cfile
|
|||
|
|
#compile afile
|
|||
|
|
|
|||
|
|
|
|||
|
|
The TopSpeed system will automatically run the appropriate "compiler" for each specified type of file - ie
|
|||
|
|
compiling the .c file and assembling the .a file.
|
|||
|
|
|
|||
|
|
|
|||
|
|
However, programmers should note that there are various rules that must be adhered to in writing
|
|||
|
|
assembler modules for Epoc programs. See the /ntroduction chapter of the PLIB Reference manual in the
|
|||
|
|
first instance.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note: the TopSpeed system will give an error message, and terminate, if there are two possible files each
|
|||
|
|
candidates as the source for of a #compile statement - for example, if the files cfile.a and cfile.c both exist
|
|||
|
|
in a directory. As another example, if a directory contains files query.c and query.rc, the statement
|
|||
|
|
#compile query will again result in an error - since the TopSpeed system regards the .rc file as a possible
|
|||
|
|
source file too. All these cases can be circumvented by giving the extension explicitly in the #command
|
|||
|
|
statement - eg #compile query.c.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Other advanced use of the project file system
|
|||
|
|
|
|||
|
|
|
|||
|
|
The TopSpeed documentation describes many possible ways to exercise further control over the process of
|
|||
|
|
building program files.
|
|||
|
|
|
|||
|
|
|
|||
|
|
One general piece of advice should, however, be borne in mind: while learning to program within the
|
|||
|
|
SIBO SDK system, please accept the default configuration proposed by Psion. Only attempt to refine this
|
|||
|
|
configuration once your program is already clearly working. Otherwise, it may prove difficult to determine
|
|||
|
|
whether some unexpected program behaviour is due to a coding mistake, or to some unexpected side-
|
|||
|
|
effect of a proposed "optimisation" of the build configuration.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In any case, optimisations resulting from careful choices of PLIB or WLIB (etc) functions, are likely to
|
|||
|
|
prove more significant than any that can easily be achieved by tweaking the SIBO version of the
|
|||
|
|
TopSpeed build configuration.
|
|||
|
|
|
|||
|
|
|
|||
|
|
It is also generally a bad idea to ignore warnings from the compiler and linker (except where explicitly
|
|||
|
|
mentioned in the SDK manuals). Rather than discounting these warnings as "quirks" of the system, they
|
|||
|
|
should all be analysed and dealt with. In particular, don't be too hasty to disable "inconvenient" compiler
|
|||
|
|
warnings.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that the SIBO SDK build configuration is actually defined in two different parts:
|
|||
|
|
e in the file tsprj.txt which has to be "compiled" (using tscfg) before being used
|
|||
|
|
e in the file stdepoc.h which is always the first include file in any source module.
|
|||
|
|
|
|||
|
|
|
|||
|
|
As mentioned in the chapter on /nstallation, the file tsprj.txt released as part of the SIBO SDK modifies
|
|||
|
|
and extends the one released by Clarion themselves, by adding in details specific to the SIBO SDK
|
|||
|
|
system.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Greater control over the image file created
|
|||
|
|
|
|||
|
|
|
|||
|
|
This section explains some of the SIBO add-ons to the TopSpeed project file build system. It also covers
|
|||
|
|
standalone use of the tools edump.exe, emake.exe and eremake.exe:
|
|||
|
|
|
|||
|
|
e edump.exe provides key information about the contents of an image file
|
|||
|
|
|
|||
|
|
e emake.exe is the underlying tool which creates image files
|
|||
|
|
|
|||
|
|
e eremake.exe can be used to alter some of the "additional" contents of image files.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Priority, minimum heap, and version number
|
|||
|
|
|
|||
|
|
|
|||
|
|
Three project file variables can be used to override various defaults otherwise used when a .img file is
|
|||
|
|
created:
|
|||
|
|
|
|||
|
|
|
|||
|
|
sversion sets the version number of the .img file, which otherwise defaults to 0x100f
|
|||
|
|
|
|||
|
|
spriority sets the initial priority of the program, which otherwise defaults to 0x80
|
|||
|
|
|
|||
|
|
sheapsize sets the initial and minimum heap of the application, which otherwise defaults
|
|||
|
|
to 0x80.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The application version number can be read by various pieces of software, for example the Application
|
|||
|
|
Info command of the System application on MC computers. For more about legal version numbers, see the
|
|||
|
|
section on p_version in the PLIB Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The initial process priority may occasionally need to be specified explicitly, eg for an application that is
|
|||
|
|
part of a suite of cooperating applications. See the section on p_setpri in the PLIB Reference manual and
|
|||
|
|
also the section Priority changing in the chapter General Window Server Functions in the Window Server
|
|||
|
|
Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The value of sheapsize is the one that applications are most likely to wish to alter, since this has
|
|||
|
|
significance for error handling (see the chapter Fundamental Programming Guidelines later in this
|
|||
|
|
manual):
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the value of sheapsize is in paragraphs, eg 0x80 means 0x800 bytes ie 2 Kbytes
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the operating system will refuse to start an instance of the application if this amount of free heap
|
|||
|
|
space cannot be found for it
|
|||
|
|
|
|||
|
|
|
|||
|
|
e once started, the application will never have its heap shrunk below this value.
|
|||
|
|
The default values for these variables can be overridden in either of two ways:
|
|||
|
|
e aline such as #set heapsize=0x180 can be added into the project file
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the parameter /sheapsize=0x180 can be added to the end of the tsc command invoking the
|
|||
|
|
project file (this is evidently the same syntax as in the /smain=%1 in the supplied batch file
|
|||
|
|
make.bat).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Use of edump.exe
|
|||
|
|
|
|||
|
|
|
|||
|
|
The tool edump.exe can be used to verify the values of the above three variables (amongst others) for a
|
|||
|
|
specified .img file. For example, typing edump p_hello results in output such as
|
|||
|
|
|
|||
|
|
|
|||
|
|
EDump V2.02F (03/10/90) Copyright (C) Psion PLC 1989
|
|||
|
|
LOC: :D:\SIBOSDK\DEMO\P_HELLO.IMG IMAGE file data
|
|||
|
|
|
|||
|
|
|
|||
|
|
Image version = 200F
|
|||
|
|
|
|||
|
|
Code Segment = 01D0 (bytes)
|
|||
|
|
Initial IP = 0000
|
|||
|
|
|
|||
|
|
Stack = 1000 (bytes)
|
|||
|
|
Data = 0040 (bytes)
|
|||
|
|
Heap = 0800 (bytes)
|
|||
|
|
Data Segment = 1840 (bytes)
|
|||
|
|
Initialized data = 0030 (bytes)
|
|||
|
|
Code checksum = DA14
|
|||
|
|
|
|||
|
|
Data checksum = OBF7
|
|||
|
|
|
|||
|
|
Code Version = 100F
|
|||
|
|
Priority = 0080
|
|||
|
|
|
|||
|
|
Header size = 0040 (bytes)
|
|||
|
|
Dyl count = 0000
|
|||
|
|
|
|||
|
|
Dyl table offset = 00000000
|
|||
|
|
Image file size = 00000240 (bytes)
|
|||
|
|
|
|||
|
|
|
|||
|
|
where the default values of "Heap", "Code version", and "Priority" can all be seen.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-12
|
|||
|
|
|
|||
|
|
|
|||
|
|
3 BUILDING AN APPLICATION
|
|||
|
|
|
|||
|
|
|
|||
|
|
Deleting p_hello.img and rebuilding it via the command
|
|||
|
|
tsc /m p_hello /sversion=0x110b
|
|||
|
|
before running edump again yields identical output, except that the "Code version" line changes.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Differences between .app files and .img files
|
|||
|
|
|
|||
|
|
|
|||
|
|
Strictly speaking, there is no real difference between image files with extension .img and those with
|
|||
|
|
extension .app. For example, although the System applications on the MC and on the Series3 usually
|
|||
|
|
expect to install .app files, they will also, if requested, install suitable .img files.
|
|||
|
|
|
|||
|
|
|
|||
|
|
However, by convention a .app file contains one or more extra so-called add-files embedded within it, in
|
|||
|
|
addition to the core .img file itself. These files may include:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e a.pic file providing the icon for the application
|
|||
|
|
e a.rsc or .rzc file providing the resource file for the application
|
|||
|
|
e a.shd file providing the shell data for the application (only for Series3 applications).
|
|||
|
|
|
|||
|
|
|
|||
|
|
As such, a .app file is simply a .img file which has some associated files conveniently built into it. A
|
|||
|
|
significant advantage of a .app file is that a user cannot inadvertently sabotage the operation of the
|
|||
|
|
program by copying the .img file itself from one drive to another, but neglecting to copy one of the
|
|||
|
|
associated files.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Add-files can be added into the .img file automatically, via the operation of emake.exe, at the time the
|
|||
|
|
.img file is itself created. What controls the set of add-files used (if any) is the presence or absence of a
|
|||
|
|
suitably named add-file list (.afl) file.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Add-file lists
|
|||
|
|
|
|||
|
|
|
|||
|
|
An add-file list (afl) file is a text file containing from one to four filenames. For example, the contents of
|
|||
|
|
a file tele.afl could be:
|
|||
|
|
|
|||
|
|
|
|||
|
|
tele.pic
|
|||
|
|
tele.rsc
|
|||
|
|
tele.shd
|
|||
|
|
|
|||
|
|
|
|||
|
|
When any .pr project file is invoked that leads to the building of tele.img, the existence of a file tele.afl is
|
|||
|
|
checked for. If such a file is found, the files listed therein are combined with the core .img file to form a
|
|||
|
|
larger .img file as output. By convention, .img files that contain embedded add-files are renamed to .app
|
|||
|
|
files (though no such renaming takes place automatically).
|
|||
|
|
|
|||
|
|
|
|||
|
|
The inclusion of these embedded files can be confirmed by running the tool edump.exe as follows. Typing
|
|||
|
|
edump tele.app might yield
|
|||
|
|
|
|||
|
|
|
|||
|
|
EDump V2.02F (03/10/90) Copyright (C) Psion PLC 1989
|
|||
|
|
LOC: :E:\SIBOSDK\HWDEMO\TELE.APP IMAGE file data
|
|||
|
|
|
|||
|
|
|
|||
|
|
Image version = 200F
|
|||
|
|
|
|||
|
|
Code Segment = 1EDO (bytes)
|
|||
|
|
|
|||
|
|
Initial IP = 0000
|
|||
|
|
|
|||
|
|
Stack = 1000 (bytes)
|
|||
|
|
|
|||
|
|
Data = 0690 (bytes)
|
|||
|
|
|
|||
|
|
Heap = 0800 (bytes)
|
|||
|
|
|
|||
|
|
Data Segment = 1E90 (bytes)
|
|||
|
|
|
|||
|
|
Initialized data = 03C0 (bytes)
|
|||
|
|
|
|||
|
|
Code checksum = 33DF
|
|||
|
|
|
|||
|
|
Data checksum = 3033
|
|||
|
|
|
|||
|
|
Code Version = 100F
|
|||
|
|
|
|||
|
|
Priority = 0080
|
|||
|
|
|
|||
|
|
Header size = OOFO (bytes)
|
|||
|
|
|
|||
|
|
Add 1 offset,len = 0040 (bytes), 0074 (bytes)
|
|||
|
|
Add 2 offset,len = 00C0O (bytes), 0000 (bytes)
|
|||
|
|
Add 3 offset,len = 00C0O (bytes), O02E (bytes)
|
|||
|
|
Dyl count = 0000
|
|||
|
|
|
|||
|
|
Dyl table offset = 00000000
|
|||
|
|
|
|||
|
|
Image file size = 00002380 (bytes)
|
|||
|
|
|
|||
|
|
|
|||
|
|
For the moment, the interesting data here is contained in the three lines of the form:
|
|||
|
|
|
|||
|
|
|
|||
|
|
Add n offset,len
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-13
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
These give the offsets within the combined .app file to the embedded add-files. In this case, three of the
|
|||
|
|
add-file slots are used; in general, any number from zero to four could be used.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For more discussion about various possible add-files, see the Series 3/3a Programming Guide.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A similar technique, using a DYL file list in a file with a .dfl extension, may be used to build any number
|
|||
|
|
of dynamic library (DYL) files into an application. This topic is described in more detail in the Object
|
|||
|
|
Oriented Programming Guide.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Changing the set of add-files in an image
|
|||
|
|
|
|||
|
|
|
|||
|
|
The tool eremake.exe can be used to change the set of add-files built into an image file, without needing to
|
|||
|
|
run the TopSpeed project system again, and without needing to have any files to hand apart from the
|
|||
|
|
original image file. That is, image files can be remade with new add-file contents, without the earlier .exe,
|
|||
|
|
.obj, or .c files being present.
|
|||
|
|
|
|||
|
|
|
|||
|
|
One common use of eremake is to convert eg an English language version of an application into a
|
|||
|
|
specified alternative language version. See the chapter Resource Files in the Additional System
|
|||
|
|
Information manual for a general discussion of applications that can run in more than one language.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, suppose that an application Query has all its language text isolated in a resource file
|
|||
|
|
query.rzc, which is one of the original add-files for the application. More precisely, suppose that the
|
|||
|
|
original contents of guery.afl are
|
|||
|
|
|
|||
|
|
|
|||
|
|
query.pic
|
|||
|
|
query.rzc
|
|||
|
|
query.shd
|
|||
|
|
|
|||
|
|
|
|||
|
|
Suppose further that a French version of the resource file is produced: frquery.rzc, say. Then a new .afl
|
|||
|
|
list should be created, frquery.afl say:
|
|||
|
|
|
|||
|
|
|
|||
|
|
query.pic
|
|||
|
|
frquery.rzc
|
|||
|
|
query.shd
|
|||
|
|
|
|||
|
|
|
|||
|
|
and eremake.exe should be invoked as follows:
|
|||
|
|
eremake -afrquery -o..\french\query.app query.app
|
|||
|
|
|
|||
|
|
|
|||
|
|
For a full list of possible parameters to eremake.exe, simply type eremake by itself. Note that eremake.exe
|
|||
|
|
can be used to alter the priority, minimum heap, or version number of an image file.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In the above case, the "output" file ..\french\query.app is created by "remaking" query.app with add-files
|
|||
|
|
listed in frquery.afl.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In this example, the files guery.pic and query.shd from the original version are also used for the French
|
|||
|
|
version. Clearly, these could be changed too, if required.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Further uses of emake.exe
|
|||
|
|
|
|||
|
|
|
|||
|
|
The actual conversion from .exe form into .img form is handled by the Psion-proprietary tool emake.exe,
|
|||
|
|
according to the command
|
|||
|
|
|
|||
|
|
|
|||
|
|
#run "emake —-b %af1l% -otname% -s -v%version% -p%priority% -hsheapsize% -%epoctype%
|
|||
|
|
Sname%S.exe"
|
|||
|
|
|
|||
|
|
|
|||
|
|
in the file tsprj.txt.
|
|||
|
|
For a full list of possible parameters to emake.exe, just type emake by itself.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note in particular that emake can produce other forms of final output, apart from .img files. This is
|
|||
|
|
determined by the sepoctype variable in the above command, which by default takes the value t1. Other
|
|||
|
|
possible values are t2 through +4:
|
|||
|
|
|
|||
|
|
|
|||
|
|
tl makes an image file, with characteristic extension .img
|
|||
|
|
|
|||
|
|
t2 makes a logical device driver, with characteristic extension .ldd
|
|||
|
|
t3 makes a physical device driver, with characteristic extension .pdd
|
|||
|
|
t4 makes a dynamic library, with characteristic extension .dyl.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Logical and physical device drivers are further discussed in the Writing Device Drivers chapter in the
|
|||
|
|
Additional System Information manual. Dynamic libraries are discussed in the Object Oriented
|
|||
|
|
Programming chapter of the PLIB Reference manual, and in the Object Oriented Programming Guide.
|
|||
|
|
|
|||
|
|
|
|||
|
|
3-14
|
|||
|
|
|
|||
|
|
|
|||
|
|
CHAPTER 4
|
|||
|
|
|
|||
|
|
|
|||
|
|
NOTES ON CLIB
|
|||
|
|
|
|||
|
|
|
|||
|
|
This chapter provides some additional information about the implementation of CLIB, the version of the
|
|||
|
|
TopSpeed C library for the Epoc operating system. It need be read only by developers who wish to use
|
|||
|
|
CLIB (for example, to port existing code from another program). Developers who stick to PLIB can skip
|
|||
|
|
|
|||
|
|
|
|||
|
|
this chapter entirely.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The difference between PLIB and CLIB is explained in the previous chapter.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Functions missing from the MS-DOS Jpi C library
|
|||
|
|
|
|||
|
|
|
|||
|
|
The following functions are not included in the EPOC version of CLIB because they rely on the IBM PC
|
|||
|
|
hardware, far or huge pointers, or direct MS-DOS functions calls. For many of the missing function calls
|
|||
|
|
there is an equivalent function or set of functions which may be called from either PLIB or WLIB.
|
|||
|
|
|
|||
|
|
|
|||
|
|
absread
|
|||
|
|
|
|||
|
|
_arc
|
|||
|
|
|
|||
|
|
bdos
|
|||
|
|
|
|||
|
|
biosdisk
|
|||
|
|
biosmemory
|
|||
|
|
_bios_disk
|
|||
|
|
_bios_memsize
|
|||
|
|
_bios_timeofday
|
|||
|
|
_clearscreen
|
|||
|
|
ctrlbrk
|
|||
|
|
|
|||
|
|
delay
|
|||
|
|
_dosbeginthread
|
|||
|
|
_dosfreestack
|
|||
|
|
dos creat
|
|||
|
|
_dos_findnext
|
|||
|
|
_dos_getdiskfree
|
|||
|
|
_dos_getftime
|
|||
|
|
_dos_keep
|
|||
|
|
_dos_setblock
|
|||
|
|
_dos_setfileattr
|
|||
|
|
dos. setvect
|
|||
|
|
_expand
|
|||
|
|
|
|||
|
|
execve
|
|||
|
|
farcoreleft
|
|||
|
|
farrealloc
|
|||
|
|
_ffree
|
|||
|
|
_fheapwalk
|
|||
|
|
_fmsize
|
|||
|
|
_frealloc
|
|||
|
|
_getbkcolor
|
|||
|
|
getcurdir
|
|||
|
|
getdta
|
|||
|
|
_getfillmask
|
|||
|
|
_getlogcoord
|
|||
|
|
getpsp
|
|||
|
|
|
|||
|
|
|
|||
|
|
abswrite
|
|||
|
|
|
|||
|
|
at
|
|||
|
|
|
|||
|
|
bdosptr
|
|||
|
|
biosequip
|
|||
|
|
biosprint
|
|||
|
|
_bios_equiplist
|
|||
|
|
_bios_printer
|
|||
|
|
Jochain intr
|
|||
|
|
convertcoords
|
|||
|
|
_cube
|
|||
|
|
_directwrite
|
|||
|
|
_dosendthread
|
|||
|
|
_dos_allocmem
|
|||
|
|
_dos_creatnew
|
|||
|
|
_dos_freemem
|
|||
|
|
_dos_getdrive
|
|||
|
|
_dos_gettime
|
|||
|
|
_dos_open
|
|||
|
|
dos_setdate
|
|||
|
|
_dos_setftime
|
|||
|
|
_dos_write
|
|||
|
|
execle
|
|||
|
|
execvpe
|
|||
|
|
farfree
|
|||
|
|
fcalloc
|
|||
|
|
_fheapchk
|
|||
|
|
_floodfill
|
|||
|
|
_FP_OFF
|
|||
|
|
freemem
|
|||
|
|
getcbrk
|
|||
|
|
_getcurrentposition
|
|||
|
|
getfat
|
|||
|
|
_getimage
|
|||
|
|
_getphyscoord
|
|||
|
|
|
|||
|
|
|
|||
|
|
gettime
|
|||
|
|
|
|||
|
|
|
|||
|
|
allocmem
|
|||
|
|
Awaited
|
|||
|
|
bioscom
|
|||
|
|
bioskey
|
|||
|
|
biostime
|
|||
|
|
_bios_keybrd
|
|||
|
|
_bios_serialcom
|
|||
|
|
change
|
|||
|
|
|
|||
|
|
country
|
|||
|
|
|
|||
|
|
Delay
|
|||
|
|
_displaycursor
|
|||
|
|
dosexterr
|
|||
|
|
ados_close
|
|||
|
|
_dos_findfirst
|
|||
|
|
_dos_getdate
|
|||
|
|
_dos_getfileattr
|
|||
|
|
_dos_getvect
|
|||
|
|
dos read
|
|||
|
|
_dos_setdrive
|
|||
|
|
_dos_settime
|
|||
|
|
_ellipse
|
|||
|
|
execlpe
|
|||
|
|
farcalloc
|
|||
|
|
farmalloc
|
|||
|
|
_fexpand
|
|||
|
|
_fheapset
|
|||
|
|
_fmalloc
|
|||
|
|
_FP_SEG
|
|||
|
|
geninterrupt
|
|||
|
|
_getcolor
|
|||
|
|
getdfree
|
|||
|
|
getfatd
|
|||
|
|
_getlinestyle
|
|||
|
|
_getpixel
|
|||
|
|
gettext
|
|||
|
|
|
|||
|
|
|
|||
|
|
4-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
_gettextcolor gettextinfo _gettextposition
|
|||
|
|
getvect getverify _getvideoconfig
|
|||
|
|
halloc _harderr _hardresume
|
|||
|
|
_hardretn hfree hide
|
|||
|
|
|
|||
|
|
highvideo hmemccpy hmemchr
|
|||
|
|
|
|||
|
|
hmemcmp hmemcpy hmemicmp
|
|||
|
|
hmemset hrealloc info
|
|||
|
|
|
|||
|
|
Init intdos intdosx
|
|||
|
|
|
|||
|
|
ioctl keep _lineto
|
|||
|
|
|
|||
|
|
Lock locking lowvideo
|
|||
|
|
|
|||
|
|
mktemp MK_FP movedata
|
|||
|
|
movetext _moveto ncalloc_
|
|||
|
|
|
|||
|
|
|
|||
|
|
_ms_cursor
|
|||
|
|
_ms_getpage
|
|||
|
|
_ms_getsensitivity
|
|||
|
|
_ms_reset
|
|||
|
|
_ms_setdouble
|
|||
|
|
_ms_setmickeys
|
|||
|
|
|
|||
|
|
|
|||
|
|
_ms_setrange
|
|||
|
|
|
|||
|
|
|
|||
|
|
_ms_driversize
|
|||
|
|
_ms_getpress
|
|||
|
|
_ms_getstatus
|
|||
|
|
_ms_restoredriver
|
|||
|
|
_ms_setgraphcursor
|
|||
|
|
_ms_setpage
|
|||
|
|
|
|||
|
|
|
|||
|
|
_ms_setsensitivity
|
|||
|
|
|
|||
|
|
|
|||
|
|
_ms_getmotion
|
|||
|
|
_ms_getrelease
|
|||
|
|
_ms_lightpen
|
|||
|
|
_ms_savedriver
|
|||
|
|
_ms_setinterrupt
|
|||
|
|
_ms_setposition
|
|||
|
|
|
|||
|
|
|
|||
|
|
_ms_settextcursor
|
|||
|
|
|
|||
|
|
|
|||
|
|
_ms_swapinterrupt _ms_updatescreen normvideo
|
|||
|
|
nosound Notify obsucredat
|
|||
|
|
_outtext palettecolor palettecolorused
|
|||
|
|
paletteopen parsfnm peek
|
|||
|
|
|
|||
|
|
peekb _pie poke
|
|||
|
|
|
|||
|
|
pokeb _polygon putbeneath
|
|||
|
|
_putimage putontop puttext
|
|||
|
|
randbrd randbwr readbufferln
|
|||
|
|
_rectangle _remapallpallete _remappallete
|
|||
|
|
_selectpalette SEND _setactivepage
|
|||
|
|
_stbkcolor setblock setcbrk
|
|||
|
|
_setcliprgn _setcolor setdta
|
|||
|
|
setftime _setfillmask setframe
|
|||
|
|
_setlinestyle setlogorg setpalette
|
|||
|
|
setpalettecolor _setpixel _settextcolor
|
|||
|
|
_settextposition _settextwindow settitle
|
|||
|
|
setvect setverify _setvideomode
|
|||
|
|
_setviewport _setvsualpage snapshot
|
|||
|
|
|
|||
|
|
sound spawnle spawnlpe
|
|||
|
|
spawnve spawnvpe StartProcess
|
|||
|
|
StartScheduler StopProcess StopScheduler
|
|||
|
|
tempnam textattr textbackground
|
|||
|
|
textcolor textmode tmpnam
|
|||
|
|
|
|||
|
|
top Unlock use
|
|||
|
|
|
|||
|
|
used WAIT window
|
|||
|
|
windowclose windowopen _wrapon
|
|||
|
|
_wrbufferlin
|
|||
|
|
|
|||
|
|
int86x
|
|||
|
|
|
|||
|
|
|
|||
|
|
int 86x is implemented by exactly the same code as int 86, ie the values in the segment registers struct are
|
|||
|
|
ignored. This is because in the pure small model ps=zs=ss and hence there is never any need to change
|
|||
|
|
the values in the segment registers.
|
|||
|
|
|
|||
|
|
|
|||
|
|
intr
|
|||
|
|
As for int86x above, the values in the segment registers are ignored.
|
|||
|
|
File handle conversion routine
|
|||
|
|
|
|||
|
|
|
|||
|
|
void *getRealHandle(int handle);
|
|||
|
|
|
|||
|
|
|
|||
|
|
Returns a PLIB file handle, given a CLIB file handle. Returns nut if the handle is not currently
|
|||
|
|
allocated.
|
|||
|
|
|
|||
|
|
|
|||
|
|
4-2
|
|||
|
|
|
|||
|
|
|
|||
|
|
4 NOTES ON CLIB
|
|||
|
|
|
|||
|
|
|
|||
|
|
The console channel
|
|||
|
|
|
|||
|
|
|
|||
|
|
Programs built with the CLIB start-up module automatically open a console channel. The channel is also
|
|||
|
|
automatically assigned to stdin, stdout and stderr, unless they have been redirected.
|
|||
|
|
|
|||
|
|
|
|||
|
|
It may prove useful to get the actual PLIB handle for the console channel. This can be achieved by either
|
|||
|
|
calling getRealHandle(fileno(stderr)) or by referencing the global _winHandle as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
extern void *winHandle;
|
|||
|
|
|
|||
|
|
|
|||
|
|
You can prevent the automatic opening of a console channel by defining the function p_xwind in your
|
|||
|
|
code, as in the following example:
|
|||
|
|
|
|||
|
|
|
|||
|
|
extern void *winHandle;
|
|||
|
|
|
|||
|
|
|
|||
|
|
void p_xwind (void)
|
|||
|
|
{
|
|||
|
|
winHandle=(void *)1;
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
int main (void)
|
|||
|
|
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
|
|||
|
|
return (0);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
You should ignore the warning, given during the linking of your program, that the symbol _p_xwind is
|
|||
|
|
duplicated.
|
|||
|
|
|
|||
|
|
|
|||
|
|
If you use this technique your program should not, of course, make any reference to stdin, stdout or
|
|||
|
|
stderr, unless you have redirected them. Setting winHandle to | (an illegal value for a handle) will
|
|||
|
|
guarantee that any such reference will fail with a panic.
|
|||
|
|
|
|||
|
|
|
|||
|
|
MS-DOS file names
|
|||
|
|
|
|||
|
|
|
|||
|
|
Applications written for the Epoc O/S should in general avoid making any assumptions about file names
|
|||
|
|
(see the Files chapter in the Plib Reference manual) and should use p_fparse and p_chdir to manipulate
|
|||
|
|
file names and navigate directory paths. However the Loc: : file system on all SIBO machines is totally
|
|||
|
|
MS-DOS compatible. Thus CLIB supports the TopSpeed STD C library functions findfirst, findnext,
|
|||
|
|
getcwd, etc which rely on MS-DOS naming conventions. However if an attempt is made to use these
|
|||
|
|
functions on other filing systems, such as rem: :, the routines will return an error.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Floating point emulator
|
|||
|
|
|
|||
|
|
|
|||
|
|
As the SIBO architecture does not allow for an 8087 maths coprocessor, all floating point is performed by
|
|||
|
|
software emulation of the 8087.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Normally the emulator code would be linked in with your program for MS-DOS exe's, but under Epoc O/S
|
|||
|
|
the emulator is provided by an LDD called SYS$8087.LDD in \sibosdk\lib\. Any programs requiring the
|
|||
|
|
emulator will automatically load the LDD and free it again when it is no longer required. This has the
|
|||
|
|
advantage of saving about 8K of code from your program and allows the LDD to be shared by multiple
|
|||
|
|
processes.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The C startup module (see r_emul.a) will look for the LDD in the directory in which your program was
|
|||
|
|
executed. If it is not found the it will use the environment variable ems (remember to use capitals for the
|
|||
|
|
name as environment variables in Epoc O/S are case sensitive).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Panic 80
|
|||
|
|
|
|||
|
|
|
|||
|
|
An application which terminates with a "panic 80" before it even starts has almost certainly failed to
|
|||
|
|
locate SYS$8087.LDD. There are three steps that can be taken to avoid the panic:
|
|||
|
|
|
|||
|
|
|
|||
|
|
move a copy of the LDD into the directory where the program will execute from
|
|||
|
|
set the environment variable ems appropriately (eg using a short program)
|
|||
|
|
rewrite the program so that it does not require the use of the LDD.
|
|||
|
|
|
|||
|
|
|
|||
|
|
See the Floating Point chapter of the Plib Reference manual for some more details.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that floating point instructions can easily be generated unexpectedly (eg to push or pop floating point
|
|||
|
|
registers) if the recommended build configuration pragmas are "improved" in any way - resulting in panic
|
|||
|
|
80s "out of the blue". If in doubt, inspect the object code using the SIBO Debugger (or use the TopSpeed
|
|||
|
|
disassembler, tsda).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Building the CLIB library and header objects
|
|||
|
|
|
|||
|
|
|
|||
|
|
To build the CLIB library you must have purchased the Professional variant of the SIBO SDK. This
|
|||
|
|
version includes the C Library Source Kit and the corresponding EPOC CLIB Library Source. Since some
|
|||
|
|
of the EPOC CLIB source modules are written in C++, you will also need to have separately purchased
|
|||
|
|
TopSpeed C++.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Simply startup TS in the SRC directory of SIBOSDK. Select CLIB as the project file and then MAKE the
|
|||
|
|
project. The libraries and objects will be generated in the SRC directory and need to be copied into the LIB
|
|||
|
|
directory. There is a batch file IVST.BAT which will do this for you.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that, in addition to the CLIB library, there is also an RLIB component. This contains elements that
|
|||
|
|
are common between CLIB and PLIB.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The source code modules for PLIB and WLIB are currently in Turbo Assembler format and are not
|
|||
|
|
buildable using the TopSpeed assembler. They have not been included in this release of the SDK. The vast
|
|||
|
|
majority in any case are simple shells which just juggle registers.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Cautionary note
|
|||
|
|
|
|||
|
|
|
|||
|
|
It is advisable to tread cautiously when changing the library, and under no circumstances should the
|
|||
|
|
pragmas be changed in either TSPRJ.TXT or STDEPOC.H.
|
|||
|
|
|
|||
|
|
|
|||
|
|
CHAPTER 5
|
|||
|
|
|
|||
|
|
|
|||
|
|
FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
Introduction
|
|||
|
|
|
|||
|
|
|
|||
|
|
In some ways, this chapter may be viewed as being among the most important in the whole of the SDK.
|
|||
|
|
Follow the Guide-lines here and your programs have a good chance of possessing the following qualities:
|
|||
|
|
|
|||
|
|
|
|||
|
|
user responsiveness users will not be kept waiting impatiently if they want to interact
|
|||
|
|
with an application whilst it is busy - eg to cancel some operation
|
|||
|
|
part-way completed
|
|||
|
|
|
|||
|
|
|
|||
|
|
error robustness data will not suddenly be lost when run-time errors occur such as
|
|||
|
|
shortage of system memory (bear in mind that such errors are
|
|||
|
|
almost inevitable on a multi-tasking computer, when the system
|
|||
|
|
memory can become unexpectedly used up by other applications)
|
|||
|
|
|
|||
|
|
|
|||
|
|
architectural robustness changes in user requirements or in implementation tactics should
|
|||
|
|
not lead to the whole code becoming unmaintainable.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Of course, practice of standard general programming principles - such as modular programming, data
|
|||
|
|
hiding, egoless programming, designing prior to coding (not to mention adequate requirements
|
|||
|
|
specification prior to design), and a structured approach to validation and testing - all have important
|
|||
|
|
roles to play in the production of quality SIBO applications. But there are additional programming
|
|||
|
|
principles that have particular importance within the SIBO environment, and it is these that this chapter
|
|||
|
|
addresses. These principles should complement the ones good programmers from other backgrounds
|
|||
|
|
already practice.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Incidentally, just as the merits of the above-mentioned "standard" programming principles are not always
|
|||
|
|
immediately obvious (data hiding is a good example), but rather have to be learned, so it is with some of
|
|||
|
|
the principles outlined in this chapter. Their importance has become clear to the programming team at
|
|||
|
|
Psion only gradually, over several years’ experience. It is understandable that experienced programmers
|
|||
|
|
from other backgrounds may wish to rush over this chapter, believing its contents to be inapplicable to
|
|||
|
|
them, but that would almost certainly be a mistake.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Again, there is of course no substitute for a wide-ranging knowledge of which library functions are
|
|||
|
|
available. Developers wishing to produce quality applications will naturally have to spend some
|
|||
|
|
considerable time familiarising themselves with the contents of the reference manuals within the SDK, so
|
|||
|
|
as to be able to spot the right function to use in any particular coding situation. This knowledge cannot be
|
|||
|
|
acquired simply by assenting to the set of programming principles covered in this chapter. But conversely,
|
|||
|
|
wide knowledge of the set of available function calls is insufficient, by itself, to produce programs with the
|
|||
|
|
traits listed at the start of this chapter.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Other related documentation
|
|||
|
|
|
|||
|
|
|
|||
|
|
Applications which are multi-lingual (eg which present English language messages on an English
|
|||
|
|
language computer, French language messages on a French language computer, and so on) pose their own
|
|||
|
|
set of programming problems. These are discussed in the course of the Resource Files chapter of the
|
|||
|
|
Additional System Information manual. (Resource files are a tool of particular importance for multi-
|
|||
|
|
lingual applications.) Note that these problems are shared between applications which are actually multi-
|
|||
|
|
lingual and those that are potentially multi-lingual: it is better to design support for multi-linguality in
|
|||
|
|
from the start, than trying to add it on afterwards.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Graphics programming has its own particular set of do's and dont's, in order that (for example) flicker-
|
|||
|
|
free redrawing and automated screen update take place. These are discussed at various places in the SDK,
|
|||
|
|
for example, in the Window Server Reference manual, and also in the Programming in HWIF manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Avoidance of excessive RAM usage, and also of "stack windup", are also of considerable importance
|
|||
|
|
within the SIBO architecture. Specific advice on these regards are scattered throughout the SDK; the
|
|||
|
|
present brief note simply has the purpose of drawing attention to the topic.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Finally, the task of designing the user interface (menus, dialogs, and so on) is another that poses its own
|
|||
|
|
special problems - programmers who labour under the misapprehension that user interfaces are "easy" to
|
|||
|
|
design almost invariably produce poor user interfaces. Guide-lines on these matters may be found within
|
|||
|
|
the object oriented documentation parts of the SDK.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The source code for the examples
|
|||
|
|
|
|||
|
|
|
|||
|
|
The bulk of this chapter consists of a lengthy analysis of a suite of example programs. These build in four
|
|||
|
|
stages - Events, Events2, Events3, and Events4 - to a program that can simultaneously process:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e keyboard input
|
|||
|
|
e the expiry of a timer
|
|||
|
|
e reports of the completion of a sub-process
|
|||
|
|
e data received from a serial port
|
|||
|
|
whilst all the time carrying on some compute-bound activity "in background"
|
|||
|
|
|
|||
|
|
|
|||
|
|
At any given moment, the program cannot predict which of its five possible "event sources" will be the
|
|||
|
|
next to require CPU. As such, the program amply demonstrates the three vital themes of multi-
|
|||
|
|
threadedness, asynchronous i/o, and yielding CPU:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e = multi-threadedness means that more than one set of activity takes place simultaneously within
|
|||
|
|
the program, with each different flow of activity being handled by its own "thread" of code
|
|||
|
|
|
|||
|
|
|
|||
|
|
e¢ — asynchronous i/o means that the queuing of a read request (or write request) on an i/o channel is
|
|||
|
|
separated in code from the completion of that request
|
|||
|
|
|
|||
|
|
|
|||
|
|
e yielding CPU means that lengthy calculations are broken down into subcomponents that are
|
|||
|
|
executed separately, with gaps in between so that some more urgent event source can be attended
|
|||
|
|
to, if necessary.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Although the program itself has limited practical use, it demonstrates the basic architectural principles
|
|||
|
|
that all sophisticated Epoc programs are bound to have to consider.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The source code for these four stages of Events can be installed from disc (SIBOSDK\DEMO), together
|
|||
|
|
with that of an associated "sub-process" application, Subproc. Readers are urged to take the time to build
|
|||
|
|
these applications and to experiment with them, in particular trying out some of the suggestions made in
|
|||
|
|
this chapter for how these programs could be modified.
|
|||
|
|
|
|||
|
|
|
|||
|
|
User interface
|
|||
|
|
|
|||
|
|
|
|||
|
|
The user interface of these example programs has deliberately been kept spartan. All screen drawing is to
|
|||
|
|
a "console terminal" that is 25 characters wide and 9 characters deep.
|
|||
|
|
|
|||
|
|
|
|||
|
|
These decisions have the advantage that:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the program works equally well on all different SIBO computers (even on the HC, where the
|
|||
|
|
screen is smallest)
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ considerations about interfacing with the Window Server - necessary in order to achieve more
|
|||
|
|
graphically appealing displays - can be postponed while focusing instead on multi-threadedness,
|
|||
|
|
asynchronous i/o, and yielding CPU.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Various examples of Window Server programs demonstrating multi-threadedness (et al) can be found
|
|||
|
|
within the SDK. For example, the Writing Software for the HC chapter of the HC Programming Guide
|
|||
|
|
discusses an application called Gauge, that will in fact run happily (with only minor adjustments) on a
|
|||
|
|
Series 3. Again, the Programming in HWIF manual contains a large set of example programs, all of
|
|||
|
|
which interface with the Window Server.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-2
|
|||
|
|
|
|||
|
|
|
|||
|
|
5 FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
A first look at multiple event sources
|
|||
|
|
|
|||
|
|
|
|||
|
|
The main routine in Events is as follows (the individual calls made, including the Plib calls, are discussed
|
|||
|
|
below):
|
|||
|
|
|
|||
|
|
|
|||
|
|
GLDEF_C VOID main(VOID)
|
|||
|
|
{
|
|||
|
|
OpenConsole();
|
|||
|
|
DrawBorder() ;
|
|||
|
|
OpenTimer () ;
|
|||
|
|
timint=10;
|
|||
|
|
QueueTimer ();
|
|||
|
|
QueueKey () ;
|
|||
|
|
FOREVER
|
|||
|
|
{
|
|||
|
|
p_iowait ();
|
|||
|
|
if (keystat!=E_FILE_PENDING)
|
|||
|
|
{
|
|||
|
|
if (key. keycode==W_KEY_ESCAPE)
|
|||
|
|
p_exit (0);
|
|||
|
|
if (key.keycode>='1' && key.keycode<='9')
|
|||
|
|
SetTimInt (2* (key. keycode-'0'));
|
|||
|
|
QueueKey () ;
|
|||
|
|
}
|
|||
|
|
else if (timstat!=E_FILE_PENDING)
|
|||
|
|
{
|
|||
|
|
if (counter++==MAX_COUNT)
|
|||
|
|
counter=1;
|
|||
|
|
DisplayCount ();
|
|||
|
|
QueueTimer ();
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
Schematically, the code is as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
GLDEF_C VOID main(VOID)
|
|||
|
|
{
|
|||
|
|
INITIALISE ();
|
|||
|
|
QueueTimer () ;
|
|||
|
|
QueueKey () ;
|
|||
|
|
FOREVER
|
|||
|
|
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
p_iowait ();
|
|||
|
|
if (keystat!=E_FILE_PENDING)
|
|||
|
|
{
|
|||
|
|
PROCESS_KEY () ;
|
|||
|
|
QueueKey () ;
|
|||
|
|
}
|
|||
|
|
else if (timstat!=E_FILE_PENDING)
|
|||
|
|
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
PROCESS_TIMER() ;
|
|||
|
|
QueueTimer();
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
in which it is clear that the program has two event sources - keypresses and the expiry of a timer.
|
|||
|
|
|
|||
|
|
|
|||
|
|
What the program actually does is to update a numeric count (displayed on the screen) regularly, on a
|
|||
|
|
timer. The rate at which the timer fires is determined by which keys the user presses:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e it starts off firing once every second
|
|||
|
|
|
|||
|
|
|
|||
|
|
e if the user presses the 2 key, the timer changes to firing once every 2/5 of a second (so that the
|
|||
|
|
numbers tick over more rapidly)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e if the user presses the 9 key, the timer changes to firing once every 9/5 of a second (so that the
|
|||
|
|
numbers tick over more slowly)
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
and so on. Further, every time a numeric key is pressed, the existing timer request is cancelled, and the
|
|||
|
|
timer reset - so that pressing repeatedly on keys such as 8 and 9 can have the effect of "stalling" the
|
|||
|
|
counter altogether.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The program exits in response to the ESC key being pressed. All other keys are ignored.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Remarks on timers
|
|||
|
|
|
|||
|
|
|
|||
|
|
One simple approach to programming with delays is to call a function such as p_sleep, which effectively
|
|||
|
|
suspends the application for a specified amount of time.
|
|||
|
|
|
|||
|
|
|
|||
|
|
This approach could be adopted in Events, were it not for the fact that, when the application is suspended,
|
|||
|
|
it cannot respond to a keypress. The keypress will only be received when the application "wakens up"
|
|||
|
|
again.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Now this might not be too much of a loss for very small time delays, but it is of course unacceptable for
|
|||
|
|
longer delays. For example, a program might wish to perform some housekeeping or maintenance once
|
|||
|
|
every twenty four hours - or simply update the display in a dialog once every two seconds, whilst allowing
|
|||
|
|
the user to cancel out of the dialog at any time. That is, whilst routines such as p_sleep certainly have a
|
|||
|
|
role to play, they cannot handle all timer requirements in programs.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A next possible approach would be to design a routine which, when called, suspended the application until
|
|||
|
|
the specified time elapsed or a keypress is received - whichever happens first. Indeed, there is a call with
|
|||
|
|
just this specification in the Opl programming language (pause when used with a negative time delay).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Actually, this routine would satisfy the requirements of Events perfectly. However, it has the severe
|
|||
|
|
drawback of lack of architectural openness. That is, suppose the application has to be modified at a later
|
|||
|
|
date, to be able to respond to another sort of event source - eg the arrival of data at a serial port, or an
|
|||
|
|
interprocess message from another application. Alternatively, the application may need to carry on some
|
|||
|
|
continuous activity, whilst waiting for the timer to expire. In either case, a more general approach is
|
|||
|
|
required.
|
|||
|
|
|
|||
|
|
|
|||
|
|
This more general approach is the mechanism by which the queuing of a timer is separated, in code, from
|
|||
|
|
the completion of the timer. In the above code, the timer is queued by the call queueTimer, whereas the
|
|||
|
|
completion of the timer occurs within the p_iowait call. (See later for the details.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
This kind of code separation between the queuing of a request and the completion of the request is known
|
|||
|
|
as asynchronous - because there is no automatic synchronisation of the two phases (as occurs, for
|
|||
|
|
example, in a call such as p_sleep).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Remarks on keypresses
|
|||
|
|
|
|||
|
|
|
|||
|
|
A routine such as p_getch is to keypresses what p_sleep is to timers - in both cases, the program is
|
|||
|
|
effectively suspended until the request is completely satisfied.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Just as there is a place for p_sleep in programming, so also there is a place for p_getch. However, each is
|
|||
|
|
generally inappropriate when there is more than one event source current - as here.
|
|||
|
|
|
|||
|
|
|
|||
|
|
So the call p_getch is split into two parts: the request for a keypress to be delivered, inside the call
|
|||
|
|
Queuekey, and the delivery of the keypress - inside p_iowait.
|
|||
|
|
|
|||
|
|
|
|||
|
|
More on p_iowait
|
|||
|
|
|
|||
|
|
|
|||
|
|
The call p_iowait is where the application gets suspended, while it waits for the completion of some or
|
|||
|
|
other event. But whilst p_sleep only returns when the associated timer expires, and p_getch only returns
|
|||
|
|
when a keypress is delivered, p_iowait returns when any known event has completed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Of course, sometimes the application won't get suspended at all when it calls p_iowait - on account of a
|
|||
|
|
queued request already having completed. For example, during the time Events is inside the code
|
|||
|
|
PROCESS_TIMER, the user may have pressed a key, in which case the subsequent call to p_iowait will
|
|||
|
|
return immediately (not that the application needs to worry about this, however).
|
|||
|
|
|
|||
|
|
|
|||
|
|
The way p_iowait works is by consulting the value of the i/o semaphore for the process. Each process has
|
|||
|
|
an i/o semaphore assigned to it. These semaphores are maintained in the private data space of the
|
|||
|
|
operating system.
|
|||
|
|
|
|||
|
|
|
|||
|
|
An i/o semaphore commonly has its value changed in either of two ways:
|
|||
|
|
e it is decremented whenever a call to p_iowait is made
|
|||
|
|
|
|||
|
|
|
|||
|
|
e it is incremented whenever some piece of software "signals" the application.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-4
|
|||
|
|
|
|||
|
|
|
|||
|
|
5 FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, whenever a timer expires, the operating system timer device signals the application which
|
|||
|
|
owns the timer. Again, whenever the Window Server delivers a keypress to an application, it signals that
|
|||
|
|
application. In general, the completion of any i/o request always involves the application being signalled.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The i/o semaphore of an application initially has the value zero. A call to p_iowait only returns when the
|
|||
|
|
i/o semaphore is non-negative. Given that the call to p_iowait starts by decrementing the semaphore, the
|
|||
|
|
call will return only when "something has happened".
|
|||
|
|
|
|||
|
|
|
|||
|
|
For more details about p_iowait and i/o semaphores in general, see the Plib Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that the SIBO Debugger has a menu command (Process Status) which displays the value of the i/o
|
|||
|
|
semaphore of a process (amongst other information). The Spy application discussed in the Series 3
|
|||
|
|
Programming Guide has a similar feature, which allows the i/o semaphores of all different running
|
|||
|
|
processes to be viewed simultaneously.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Status words: the other side of p_iowait
|
|||
|
|
|
|||
|
|
|
|||
|
|
When a program returns from a call to p_sleep, it knows that it is a timer that has expired. Likewise,
|
|||
|
|
when a program returns from a call to p_getch, it knows that a keypress has been delivered. However,
|
|||
|
|
when a call to p_iowait returns, no such information is immediately available. All the application knows
|
|||
|
|
at this point is that some event has completed - not which event.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In general, the task of determining which events are indeed ready to be processed involves two factors:
|
|||
|
|
¢ knowing which event sources are active - having had requests made on them
|
|||
|
|
e knowing which of this subset have completed their requests.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For the moment, the first of these points can be ignored (but see later), with attention given to the notion
|
|||
|
|
of the status word of an asynchronous request:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e when the request is made, an address of a status word is specified (recall that a "word" is two
|
|||
|
|
adjacent bytes)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e when the request is made, the value E_rFILE_PENDING gets written to this word
|
|||
|
|
|
|||
|
|
|
|||
|
|
e when the request completes, a value other than &_FILE_PENDING is written to this word (the
|
|||
|
|
actual value varying depending on the type of asynchronous request)
|
|||
|
|
|
|||
|
|
|
|||
|
|
Writing to the status word takes place just before the i/o semaphore for the application is signalled. Both
|
|||
|
|
these steps are integral to the SIBO mechanism of p_iowait.
|
|||
|
|
|
|||
|
|
|
|||
|
|
All this explains the code in Events immediately after the call to p_iowait: the different status words are
|
|||
|
|
polled in turn, in order to find one whose value is no longer E_FILE_PENDING.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Prioritisation of event sources
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that the order in which the status words are polled implicitly prioritises the different event sources.
|
|||
|
|
For it is possible for more than one asynchronous event to have completed; in this case, the first one of the
|
|||
|
|
two polled will be the one which gets the first response.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note in particular that the order in which events are processed need bear no direct relation to the order in
|
|||
|
|
which the events actually completed. An event source lower down the priority listing can be "locked out"
|
|||
|
|
by rapidly firing event sources higher in the listing. In fact, code can often be written which depends on
|
|||
|
|
this prioritisation - so that a lower priority event source is only serviced when all higher priority event
|
|||
|
|
sources have quietened down.
|
|||
|
|
|
|||
|
|
|
|||
|
|
I/O devices in general
|
|||
|
|
|
|||
|
|
|
|||
|
|
In this example, keypresses are delivered by the console device. Likewise, timer expiry is handled by the
|
|||
|
|
timer device. The console device and the timer device are both instances of general so-called i/o devices,
|
|||
|
|
all of which possess a common interface:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e before using an i/o device, an application has to open a channel to it
|
|||
|
|
© once opened, various services can be requested via the channel
|
|||
|
|
e these services can all in principle be requested either synchronously or asynchronously
|
|||
|
|
|
|||
|
|
|
|||
|
|
e if an i/o device channel is no longer needed, the resources it consumes (eg memory) can be
|
|||
|
|
released by closing the channel.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Channels to i/o devices are opened by means of the p_open call, in which the 1/o device has to be specified
|
|||
|
|
by name. Another parameter to the p_open call also defines where the handle of the channel will be
|
|||
|
|
written.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The handle returned by p_open can then be used to request other services from the i/o device. It can also
|
|||
|
|
be passed as a parameter to p_close, to close the channel down again.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The way synchronous requests are made, via an i/o channel, is to use a p_iow call (or a convenience
|
|||
|
|
routine that layers over this). Asynchronous requests are made using a p_ioa (or p_ioc) call.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, the call to position the console cursor, inside the routine write in events.c, is as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
P_POINT pos;
|
|||
|
|
WORD func;
|
|||
|
|
|
|||
|
|
|
|||
|
|
pOS.xX=X;
|
|||
|
|
Pos.y=y;
|
|||
|
|
|
|||
|
|
func=P_SCR_POSA;
|
|||
|
|
|
|||
|
|
p_iow4 (conH, P_FSET, &func, &pos) ;
|
|||
|
|
|
|||
|
|
|
|||
|
|
This is a synchronous call because there is no point in calling it asynchronously: the effect of this call
|
|||
|
|
(setting the cursor position) is always (virtually) immediate: there is no scope for any extended delay as it
|
|||
|
|
is carried out.
|
|||
|
|
|
|||
|
|
|
|||
|
|
On the other hand, the code for queuekKey is
|
|||
|
|
|
|||
|
|
|
|||
|
|
LOCAL_C VOID QueueKey (VOID)
|
|||
|
|
{
|
|||
|
|
p_ioa4 (conH, P_FREAD, &keystat, &key) ;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
which is clearly asynchronous. (The 'a' in "p_ioa" stands for asynchronous.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
By chance, it turns out that these two calls to p_ioa and p_iow have the same number of parameters. This,
|
|||
|
|
however, is only the case because the P_FREAD request requires one less parameter than the P_FSET
|
|||
|
|
request. In general, an asynchronous request always has one more parameter than the corresponding
|
|||
|
|
synchronous request - namely the status word, whose address has to be passed in the asynchronous case.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For more on the p_io? functions (including the significance of the numeric suffices to the function
|
|||
|
|
names), see the Plib Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The console device
|
|||
|
|
|
|||
|
|
|
|||
|
|
The Events application uses the console device - as opposed to just making calls like p_printf - for two
|
|||
|
|
reasons:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e as discussed already, the console device supports an asynchronous version of p_getch
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the console device supports repositioning of the cursor position - which fact is relied upon heavily
|
|||
|
|
in the application.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For a full specification of the console device, see the corresponding chapter in the //O Devices Reference
|
|||
|
|
manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
How to cancel a timer
|
|||
|
|
|
|||
|
|
|
|||
|
|
The code inside cancelTimer merits some attention:
|
|||
|
|
|
|||
|
|
|
|||
|
|
LOCAL_C VOID CancelTimer (VOID)
|
|||
|
|
{
|
|||
|
|
p_iow2 (timH, P_FCANCEL) ;
|
|||
|
|
p_waitstat (&timstat) ;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
First, the P_FCANCEL service is requested. This is itself a synchronous request, completing at once.
|
|||
|
|
|
|||
|
|
|
|||
|
|
However, the way the generic service P_FCANCEL works in device drivers is never to retract the earlier
|
|||
|
|
request, but rather to precipitate its completion. It cannot retract it in general because it may already have
|
|||
|
|
completed by the time the p_FcANCEL request is made:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e if the request has already completed, the p_rcaNncEL does precisely nothing
|
|||
|
|
|
|||
|
|
|
|||
|
|
e if the request is still outstanding, it is completed forthwith, with the value E_FILE_caANcEL being
|
|||
|
|
written to the status word, and with the application being signalled (on account of the fact that
|
|||
|
|
the earlier request has now completed, albeit precipitously).
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-6
|
|||
|
|
|
|||
|
|
|
|||
|
|
5 FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
In either case, the application will be signalled - either before the p_rcanczg , or after it. Accordingly, this
|
|||
|
|
signal has to be "processed" (or "used up"). This is the purpose of the subsequent call to p_waitstat. For
|
|||
|
|
more details about p_waitstat, see the Plib Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Omitting to call p_waitstat after making a p_FCANCEL request is a common error. The result of this error
|
|||
|
|
is that the next call to p_iowait will return at once, even though none of the remaining active event
|
|||
|
|
sources is ready to deliver an event.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For more details about the timer device in general, see the chapter Time, Timers and Dates in the Plib
|
|||
|
|
Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Where to declare status words
|
|||
|
|
|
|||
|
|
|
|||
|
|
On the subject of common programming errors in conjunction with asynchronous i/o, perhaps the most
|
|||
|
|
common one has yet to be mentioned. This is the mistake of declaring status words on the stack of some
|
|||
|
|
routine which will have returned long before the asynchronous request completes. The status word will
|
|||
|
|
now be a piece of random data - perhaps on the stack of another routine - and random damage can ensue
|
|||
|
|
when it is in due course written to.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Status words should always be declared either in static data (as in Events), or in a control block allocated
|
|||
|
|
from the heap.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A first look at error handling
|
|||
|
|
|
|||
|
|
|
|||
|
|
Every time a function call is written into a SIBO program, the programmer should consider the question:
|
|||
|
|
could a run-time error occur in the middle of this function? And if so, what would happen?
|
|||
|
|
|
|||
|
|
|
|||
|
|
Chief amongst these possible errors is lack of memory. This can occur in three different ways:
|
|||
|
|
e the application has reached the limit of its 64k data segment
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the application is using less than 64k itself, but there is no system memory available for it to be
|
|||
|
|
given more heap space
|
|||
|
|
|
|||
|
|
|
|||
|
|
e another program with which the application is cooperating runs out of memory.
|
|||
|
|
Other errors that need to be considered include:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e resources not being available because another application is already using them (eg serial port or
|
|||
|
|
sound device driver, or even a file that is currently open by another application)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e disk-based errors such as disk full, disk corrupt, or disk removed
|
|||
|
|
e the unexpected disappearance of the remote filing system (rem: :)
|
|||
|
|
e comms failures such as serial overrun, parity error, or line failure.
|
|||
|
|
|
|||
|
|
|
|||
|
|
These errors cannot be dismissed with the philosophy that, in an ideal world, they will not happen.
|
|||
|
|
Instead, they can and will happen, despite the best endeavours of the programmer. SSDs becoming full up,
|
|||
|
|
comms cables being removed, or a file already being open by another program, are all problems that arise
|
|||
|
|
naturally in the operation of a SIBO computer.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Whatever the cause of a run-time error, applications should take every care that no data entered by the
|
|||
|
|
user is lost. Another requirement - to avoid parts of memory being permanently tied up for no purpose - is
|
|||
|
|
that partly assembled data constructs which cannot be completely assembled, owing to a run-time error at
|
|||
|
|
a later stage, should be carefully disassembled again.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Error handling in Events
|
|||
|
|
|
|||
|
|
|
|||
|
|
Looking at the source code in events.c, it is clear that three different types of error are considered:
|
|||
|
|
e failure to open the timer device
|
|||
|
|
e failure to open the console device
|
|||
|
|
|
|||
|
|
|
|||
|
|
e failure to set the size of the console screen.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
None of the other function calls have any possibility of run-time error, as can be verified by considering
|
|||
|
|
them all individually. (In fact, considering every call individually for possibilities of run-time error has to
|
|||
|
|
be the norm when developing applications.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
It is worth considering the above three possible errors in a little more detail. For example, opening a timer
|
|||
|
|
can fail for two reasons:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e lack of memory for the timer control block in the application data space
|
|||
|
|
e lack of memory in the operating system dataspace for the real timer entry.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Now whilst an application may be able to ensure that the first possibility never arises - by means of setting
|
|||
|
|
its minimum heap appropriately - it can never be sure of preventing the second case. The number of
|
|||
|
|
timers allocated in operating system dataspace depends not on circumstances within the original
|
|||
|
|
application, but rather on what other applications have done. If other applications running simultaneously
|
|||
|
|
happen to make heavy use of timer resources, the operating system may not be able to set aside the one
|
|||
|
|
timer channel requested by Events.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Should this occur, the code in openTimer and Check ensure that a suitable error message is passed back to
|
|||
|
|
the user. The user can then take action to shut down some of the other applications running
|
|||
|
|
simultaneously on the computer, before trying to start Events again.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The case of the channel to the console device is similar. This time, it is resources of (for example) the
|
|||
|
|
Window Server which may be unable to meet the request made. Likewise when the console window is
|
|||
|
|
sized (at which time various arrays or back-up bitmaps need to be allocated).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Fatal errors and non-fatal errors
|
|||
|
|
|
|||
|
|
|
|||
|
|
The three possible errors in Events are all treated as being fatal: the application initialisation fails, so the
|
|||
|
|
application terminates.
|
|||
|
|
|
|||
|
|
|
|||
|
|
This kind of action makes good sense for errors during the initialisation of an application, but cannot on
|
|||
|
|
the whole be tolerated for errors during the main phase of an application (ie after the initialisation is
|
|||
|
|
complete). By this time, the user may well have committed some data into the application, which would be
|
|||
|
|
lost if the application suddenly terminated.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In these cases, a retry philosophy is much more appropriate: the application cleans up any interim semi-
|
|||
|
|
allocated resources, "rolls back" to its previous good state, and presents an error message informing the
|
|||
|
|
|
|||
|
|
user what has happened. It is up to the user to try to correct the error condition, and then re-initiate the
|
|||
|
|
|
|||
|
|
previous action.
|
|||
|
|
|
|||
|
|
|
|||
|
|
When resources need to be tidied explicitly
|
|||
|
|
|
|||
|
|
|
|||
|
|
It may be noted that there are no calls to p_close in events.c. These calls are unnecessary in this program,
|
|||
|
|
because the channels are automatically closed, by the operating system, when the application exits.
|
|||
|
|
|
|||
|
|
|
|||
|
|
This situation must be contrasted carefully with that when a resource (such as a channel to an i/o device)
|
|||
|
|
is used transiently by an application. In this case, it must be freed as soon as it is no longer needed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Inter-Process Communication Events2 and Subproc
|
|||
|
|
|
|||
|
|
|
|||
|
|
Events2 extends the functionality of Events by supporting the facility to launch a sub-process. A sub-
|
|||
|
|
process is automatically started during program initialisation, and once it has terminated, the user can
|
|||
|
|
press ENTER to re-launch it again.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The sub-process mimics the carrying out of some extended activity. When it finishes, it signals the fact of
|
|||
|
|
its completion to Events2, together with an "answer", which Events2 displays on the screen. This answer
|
|||
|
|
has in fact been calculated from a parameter passed by Events2 to Subproc on the command line.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Subproc and Events2 therefore carry out a restricted form of inter-process communication, and thereby
|
|||
|
|
illustrate some of the multi-tasking possibilities in writing software for SIBO computers.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A third event source
|
|||
|
|
|
|||
|
|
|
|||
|
|
Events2 remains alert to the possibility of a signal from Subproc, even though it is busy responding to
|
|||
|
|
timer events and keyboard events. Events2 manages this via a straightforward extension of the
|
|||
|
|
architecture in Events: one more "event source" is added into the picture.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-8
|
|||
|
|
|
|||
|
|
|
|||
|
|
5 FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
Thus there is one more status word - substat - and one more test in the main loop in main:
|
|||
|
|
|
|||
|
|
|
|||
|
|
else if (substat!=E_FILE_PENDING)
|
|||
|
|
Report Sub () ;
|
|||
|
|
|
|||
|
|
|
|||
|
|
That is, whereas main used to poll up to two status words, on returning from a call to p_iowait, it now
|
|||
|
|
polls up to three status words: subst at in addition to keystat and timstat.
|
|||
|
|
|
|||
|
|
|
|||
|
|
However, this new event source differs from the previous two in that it is not an i/o device. There is no
|
|||
|
|
p_ioa call to request notification from Subproc; rather, the corresponding "queue" call is p_1ogona.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In the line of code
|
|||
|
|
|
|||
|
|
|
|||
|
|
p_logona (pid, &ésubstat) ;
|
|||
|
|
|
|||
|
|
|
|||
|
|
the calling application (Events2) is requesting asynchronous notification of the eventual termination of the
|
|||
|
|
process identified by pia. This notification consists of two parts (now familiar):
|
|||
|
|
|
|||
|
|
|
|||
|
|
e avalue other than &_FILE_PENDING is written into substat
|
|||
|
|
e the application is signalled (so that its i/o semaphore increments).
|
|||
|
|
|
|||
|
|
|
|||
|
|
How Events2 passes data to Subproc
|
|||
|
|
|
|||
|
|
|
|||
|
|
Events2 passes its original data to Subproc via the command line.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In any case like this, there has to be an agreement between the two processes as to the format of the
|
|||
|
|
command line. Here, the protocol is established in the shared header file subproc.h, which defines the
|
|||
|
|
following struct:
|
|||
|
|
|
|||
|
|
|
|||
|
|
typedef struct
|
|||
|
|
{
|
|||
|
|
HANDLE pid;
|
|||
|
|
VOID *poff;
|
|||
|
|
ULONG data;
|
|||
|
|
} SUBPROC_CL;
|
|||
|
|
|
|||
|
|
|
|||
|
|
The members of this struct serve the following purposes:
|
|||
|
|
pid identifies the process which launched Subproc (ie Events2)
|
|||
|
|
|
|||
|
|
|
|||
|
|
poff an address within the dataspace of Events2 where Subproc should in due course write back
|
|||
|
|
the "answer" it discovers
|
|||
|
|
|
|||
|
|
|
|||
|
|
data _ the original seed data for Subproc to operate with.
|
|||
|
|
The following code sets up this struct and creates and runs Subproc:
|
|||
|
|
|
|||
|
|
|
|||
|
|
LOCAL_C VOID LaunchSub (VOID)
|
|||
|
|
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
HANDLE pid;
|
|||
|
|
|
|||
|
|
SUBPROC_CL cl;
|
|||
|
|
|
|||
|
|
TEXT subname [P_FNAMESIZE];
|
|||
|
|
|
|||
|
|
|
|||
|
|
p_fparse ("subproc.img",DatCommandPtr, &ésubname[0],0);
|
|||
|
|
cl.pid=p_getpid();
|
|||
|
|
cl.poff=(&answer) ;
|
|||
|
|
cl.data=p_date();
|
|||
|
|
if ((pid=p_execc (&subname[0],&cl,sizeof (cl) )) <0)
|
|||
|
|
{
|
|||
|
|
p_notifyerr(pid,"Failed to launch subprocess",0,0,0);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
p_logona (pid, &substat) ;
|
|||
|
|
p_presume (pid) ;
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
The variable answer is a static. Clearly, it would be a significant error to include it on the stack of
|
|||
|
|
LaunchSub, since this stack will have unwound before answer gets written to (by Subproc).
|
|||
|
|
|
|||
|
|
|
|||
|
|
As can be seen, in this example, the data value passed to Subproc is just the current time/date, as returned
|
|||
|
|
by p_date.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note the call to p_fparse, which calculates the presumed full pathname of subproc.img, under the
|
|||
|
|
assumption that this is in the same directory as events2.img. (The full path of events2.img is written to
|
|||
|
|
DatCommandPtr by the operating system, when Events2 starts running.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
For more on the operation of p_logona, see the Plib Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The code in Subproc
|
|||
|
|
|
|||
|
|
|
|||
|
|
The code in subproc.c is very straightforward:
|
|||
|
|
|
|||
|
|
|
|||
|
|
#include <p_std.h>
|
|||
|
|
#include <p_gen.h>
|
|||
|
|
#include <p_math.h>
|
|||
|
|
#include <epoc.h>
|
|||
|
|
#include "subproc.h"
|
|||
|
|
|
|||
|
|
|
|||
|
|
GLREF_C TEXT *DatCommandPtr;
|
|||
|
|
|
|||
|
|
|
|||
|
|
GLDEF_C INT main(VOID)
|
|||
|
|
{
|
|||
|
|
TEXT *pb;
|
|||
|
|
SUBPROC_CL *pcl;
|
|||
|
|
UWORD answer;
|
|||
|
|
WORD logstat;
|
|||
|
|
|
|||
|
|
|
|||
|
|
pb=DatCommandPtr+p_slen(DatCommandPtr) +1;
|
|||
|
|
|
|||
|
|
if (*pb!=sizeof (SUBPROC_CL) )
|
|||
|
|
return (E_GEN_ARG) ;
|
|||
|
|
|
|||
|
|
pcl=(SUBPROC_CL *) (pbt+1);
|
|||
|
|
|
|||
|
|
if (!p_logona(pcl->pid, &logstat) )
|
|||
|
|
{
|
|||
|
|
answer=(UWORD) (p_randl (&pcl->data) % (2*60*32) );
|
|||
|
|
p_sleept (answer) ;
|
|||
|
|
if (logstat<0)
|
|||
|
|
|
|||
|
|
p_pcpyto (pcl->pid, pcl->poff, &answer, sizeof (UWORD) ) ;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (0);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
The way Subproc mimics performing a lengthy calculation is simply to call p_sleept, for some random
|
|||
|
|
period up to two minutes in duration.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that Subproc exits at once if the command line passed to it is not of the expected type. On most SIBO
|
|||
|
|
computers, the result of an application calling p_exit with a negative value is a Notifier reporting the
|
|||
|
|
abnormal exit.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note too that just as Events2 asynchronously logs onto Subproc, Subproc logs onto Events2. However, this
|
|||
|
|
is for a different reason. Namely, Events2 might terminate in the meantime, while Subproc is busy
|
|||
|
|
"calculating". In this case, a non-negative number will be written into logstat. If Subproc ignored this
|
|||
|
|
fact and proceeded regardless to p_pcpyto data into the process currently having identifier pc1->pia, in
|
|||
|
|
all probability the call would fail - process identifiers take a long time to get re-used, and the operating
|
|||
|
|
system would ignore the p_pcpyto on account of a non-existent pid being specified. But there is always an
|
|||
|
|
outside chance that the pia will indeed be re-used by the time Subproc has completed - in which case the
|
|||
|
|
p_pepyto could cause random damage to a blameless application.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The reason there is a test on the result of the p_logona call in Subproc is to guard against the rare case of
|
|||
|
|
Events2 exiting even before Subproc reaches the p_logona call.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Mechanisms for inter-process communication
|
|||
|
|
|
|||
|
|
|
|||
|
|
The above mechanism is a very simple illustration of a form of IPC (inter-process communication). Epoc
|
|||
|
|
supports a considerable range of IPC services, chief amongst them being IPC messaging.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Messaging also involves the same principles of status words, synchronous or asynchronous requests, and
|
|||
|
|
signalling an application. In some cases, one process will signal another one explicitly, using the function
|
|||
|
|
p_iosignalbypid; in other cases, the signalling is performed by the operating system, say in response to a
|
|||
|
|
p_mfree call in an application (indicating that the message sent has been processed).
|
|||
|
|
|
|||
|
|
|
|||
|
|
See the Plib Reference manual for more details of these different forms of IPC.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-10
|
|||
|
|
|
|||
|
|
|
|||
|
|
5 FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
Debugging cooperating applications
|
|||
|
|
One method of debugging the interaction between Events2 and Subproc is as follows:
|
|||
|
|
e leave both image files in the same directory on the PC
|
|||
|
|
e in that directory, type sdbg events2 to start debugging Events2
|
|||
|
|
e place a breakpoint on the p_logona call in events2.c
|
|||
|
|
e run Events2 until it reaches this breakpoint
|
|||
|
|
|
|||
|
|
|
|||
|
|
e note incidentally that the p_fparse call in Launchsub automatically deduces that since Events2
|
|||
|
|
has been launched from a remote directory (ie on the PC), Subproc should also be launched (if
|
|||
|
|
possible) from this same remote directory
|
|||
|
|
|
|||
|
|
|
|||
|
|
e when the Debugger breaks at the p_logona call, the code and data segments for Subproc will
|
|||
|
|
already be created (by virtue of the prior p_execc call)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e refresh the main list of remote processes; select Subproc and break into it (use the Break Into
|
|||
|
|
menu command)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e scan to the beginning of main in subproc.c and set a breakpoint there
|
|||
|
|
e issue the Apply Breakpoints menu command (whence the windows will go blank)
|
|||
|
|
e switch back to the window debugging Events2 and step over the p_presume call
|
|||
|
|
|
|||
|
|
|
|||
|
|
e this will have the effect of starting the execution in Subproc - in which case the breakpoint in
|
|||
|
|
main will be reached.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Debugging now continues, with two different debugging windows - one for Events2, and one for Subproc.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Error handling in Events2
|
|||
|
|
|
|||
|
|
|
|||
|
|
The call to p_execc in Events2 can fail for a variety of reasons - chief amongst them lack of system
|
|||
|
|
memory. Note that Events2 does not treat this as a fatal error; rather, the error is reported to the user, and
|
|||
|
|
the program carries on (taking care to leave the internal variable subexist set correctly).
|
|||
|
|
|
|||
|
|
|
|||
|
|
The user has the opportunity to respond to the message by freeing up some system memory, and then
|
|||
|
|
pressing ENTER to make another attempt to launch Subproc.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Socially responsible programming in Events2
|
|||
|
|
|
|||
|
|
|
|||
|
|
There is one more change between events.c and events2.c, which actually corrects a bug deliberately left
|
|||
|
|
in Events. This change is the addition of a call to p_unmarka at the start of main.
|
|||
|
|
|
|||
|
|
|
|||
|
|
If a SIBO computer is left switched on while Events is running, it will fail to auto-switch-off subsequently.
|
|||
|
|
This is because of the regular timer activity in the program, which keeps resetting the inactivity counter of
|
|||
|
|
the computer.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Suppose that the user turns the computer off explicitly. However, if an alarm rings at some stage, Events
|
|||
|
|
will start running again, and if the user is not at hand to notice the alarm, the result will soon be flattened
|
|||
|
|
batteries - regardless of the auto-switch-off setting. (Try it and see.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
However, the addition of the call to p_unmarka prevents any activity within Events2 from resetting the
|
|||
|
|
inactivity counter. As a result, Events2 is much more socially responsible than its precursor.
|
|||
|
|
|
|||
|
|
|
|||
|
|
See the Plib Reference manual for more details on p_unmarka.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Data received from a serial port
|
|||
|
|
|
|||
|
|
|
|||
|
|
Events3 extends the functionality of Events2 by including yet another event source: data received from a
|
|||
|
|
serial port. Characters are read one at a time from the serial port and, if they are printable, they are echoed
|
|||
|
|
onto the screen.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For background information on the serial port, see the Serial Port chapter of the I/O Devices Reference
|
|||
|
|
manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-11
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Opening the serial port
|
|||
|
|
|
|||
|
|
|
|||
|
|
The serial port is an i/o device: before services such as P_FREAD can be requested from it, a suitable
|
|||
|
|
channel has to be opened.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The contents of the openSer routine in events3.c are as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
LOCAL_C VOID OpenSer ()
|
|||
|
|
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
INT ret;
|
|||
|
|
|
|||
|
|
|
|||
|
|
ret=p_open(&serH, "TTY:B",-1);
|
|||
|
|
if (ret<0)
|
|||
|
|
ret=p_open(&serH, "TTY:A",-1);
|
|||
|
|
if (ret<0)
|
|||
|
|
{
|
|||
|
|
p_notifyerr(ret,"Opening serial port",0,0,0);
|
|||
|
|
serH=0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
If the attempt to open "TTyv:8B" fails, an attempt is made to open "TTy:A" instead; only if both attempts fail
|
|||
|
|
is this fact reported to the user.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Typical reasons for it being impossible to open a serial port are that port already being in use (eg by Link
|
|||
|
|
software) or the port not being physically present.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In contrast to the retry mechanism for launching Subproc which is built into Events3, there is no
|
|||
|
|
corresponding retry mechanism for opening the serial port. A trivial amendment could be made to allow
|
|||
|
|
|
|||
|
|
|
|||
|
|
this.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Active and inactive event sources
|
|||
|
|
|
|||
|
|
|
|||
|
|
Events3 adds this fourth event source to the bottom of the prioritised list in main, which now has the
|
|||
|
|
following schematic form:
|
|||
|
|
|
|||
|
|
|
|||
|
|
GLDEF_C VOID main(VOID)
|
|||
|
|
{
|
|||
|
|
INITIALISE();
|
|||
|
|
QueueTimer ();
|
|||
|
|
QueueKey ();
|
|||
|
|
LaunchSub () ;
|
|||
|
|
QueueSer();
|
|||
|
|
FOREVER
|
|||
|
|
{
|
|||
|
|
p_iowait ();
|
|||
|
|
if (keystat!=E_FILE_PENDING)
|
|||
|
|
{
|
|||
|
|
PROCESS_KEY ();
|
|||
|
|
QueueKey ();
|
|||
|
|
}
|
|||
|
|
else if (timstat!=E_FILE_PENDING)
|
|||
|
|
{
|
|||
|
|
PROCESS_TIMER() ;
|
|||
|
|
QueueTimer ();
|
|||
|
|
}
|
|||
|
|
else if (subexist && substat!=E_FILE_PENDING)
|
|||
|
|
Report Sub ();
|
|||
|
|
else if (serH && serstat!=E_FILE_PENDING)
|
|||
|
|
{
|
|||
|
|
p_tickle();
|
|||
|
|
DisplaySerChar ();
|
|||
|
|
QueueSer ();
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-12
|
|||
|
|
|
|||
|
|
|
|||
|
|
5 FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note however that the test for whether to call Report sub has changed its form slightly. No longer is it
|
|||
|
|
sufficient just to poll substat; it is also necessary to check on the current value of subexist:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e subexist is set to TRUE When Subproc is successfully launched
|
|||
|
|
e¢ subexist 1s set back to FALSE whenever it is discovered that Subproc has completed
|
|||
|
|
e thus the only time the value of substat should be polled is when subexist iS TRUE.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Without this double check, a variety of bugs can be demonstrated - all of which stem from serial port
|
|||
|
|
events being misinterpreted as reports of Subevent completing.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Similarly, for the sake of correctness, the value of serx should be tested before going on to poll serstat:
|
|||
|
|
serH is 0 if it has proved impossible to open a serial port. (Actually, no immediate harm will ensue if the
|
|||
|
|
check on serH is omitted, given that this is the last of the event sources in the priority list.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
The reason no corresponding checks are required for the keyboard and timer event sources is that these
|
|||
|
|
event sources are always active:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the program terminates at once if it proves impossible to open a channel to these devices
|
|||
|
|
|
|||
|
|
|
|||
|
|
e every time an event is delivered from these sources, another request (for yet another event) is
|
|||
|
|
issued straightaway.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The variables serx and subexist in Events3 play the role of what are sometimes called active words for
|
|||
|
|
their event sources - complementing the roles of their status words:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e active words have to be set and cleared by the application itself
|
|||
|
|
|
|||
|
|
|
|||
|
|
e status words are written to by system software; generally, application software only reads the
|
|||
|
|
values of status words
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ active words are set when a request is made; status words are set when a request completes.
|
|||
|
|
|
|||
|
|
|
|||
|
|
One other possible advantage in maintaining active words for event sources is to avoid making the
|
|||
|
|
mistake of sending a Pp_FCANCEL request to an i/o channel which has not had a read request made on it.
|
|||
|
|
Some i/o devices panic the application if this happens.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Debugging applications with serial comms
|
|||
|
|
Programs involving serial comms are inevitably harder to debug than without serial comms.
|
|||
|
|
|
|||
|
|
|
|||
|
|
This is because the Debugger itself uses up one serial port on the computer. In general, Events3 will be
|
|||
|
|
unable to open any serial port currently being used by Link software (such as the SIBO Debugger).
|
|||
|
|
|
|||
|
|
|
|||
|
|
One possibility, however, is to use say port a to debug the application, and send serial data to the
|
|||
|
|
application via port B.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The role of p_tickle
|
|||
|
|
|
|||
|
|
|
|||
|
|
Whenever serial port data is received by Events3, a call is made to p_tickle to reset the inactivity
|
|||
|
|
counter. This prevents the computer from auto-switching off part way through processing an incoming
|
|||
|
|
stream of serial data.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that there is no requirement to make a corresponding call whenever a keypress is received, since the
|
|||
|
|
operating system does this automatically.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Finally, it would of course be an error to make this call whenever the timer expires - since this would keep
|
|||
|
|
the computer permanently switched on.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that some early versions of the Epoc operating system may fail to support p_tickle (versions prior
|
|||
|
|
to 2.11).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Yielding CPU in compute-intensive programs
|
|||
|
|
|
|||
|
|
|
|||
|
|
Events4 adds in yet another type of event source - one that is subtly different from all the others so far
|
|||
|
|
introduced. This is an event source which is always ready to run immediately. However, it is deliberately
|
|||
|
|
located in a low position in the priority listing, to ensure that other event sources are processed
|
|||
|
|
preferentially.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-13
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
A real-life example of such an event source would be a recalculation computation in a spreadsheet, or a
|
|||
|
|
reformatting calculation in a word processor. Again, a long file operation - such as building the index of a
|
|||
|
|
DBF file - should also be broken up into chunks, so as to let the application to respond to other event
|
|||
|
|
sources in the meantime. Finally, a game may think indefinitely until such time as it is told to stop.
|
|||
|
|
|
|||
|
|
|
|||
|
|
In Events4, this continual "thinking" is simulated by continually adjusting the display of part of the
|
|||
|
|
boundary of the console window. The constant visible change is meant to reflect constant internal activity.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Idle objects
|
|||
|
|
|
|||
|
|
|
|||
|
|
Event sources such as just discussed are sometimes referred to as idle objects. The meaning of the name is
|
|||
|
|
that they only get a chance to run when the application is otherwise idle. For example, if an application is
|
|||
|
|
busy responding to keypresses, it is certainly not idle, and so any idle objects have no opportunity to run.
|
|||
|
|
|
|||
|
|
|
|||
|
|
On the other hand, this name is of course potentially misleading, since the activity represented by the idle
|
|||
|
|
object is anything but idle.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The meaning of calling p_iosignal
|
|||
|
|
|
|||
|
|
|
|||
|
|
The contents of the "queue" routine for the idle object in Events4 is just the single line
|
|||
|
|
p_iosignal();
|
|||
|
|
|
|||
|
|
|
|||
|
|
Since there is no genuine i/o connected with an idle object, there is no system software that automatically
|
|||
|
|
signals the application when the i/o has completed. That is why the "queue" routine itself calls
|
|||
|
|
p_iosignal.
|
|||
|
|
|
|||
|
|
|
|||
|
|
At the same time, it might be thought that this routine should write to a status word. Actually, however,
|
|||
|
|
there is no point in doing so: what matters is simply that the event source is active; in that case, it is
|
|||
|
|
automatically ready to deliver an "event" (ie to take more CPU).
|
|||
|
|
|
|||
|
|
|
|||
|
|
Just as some event sources have no need to maintain an active word (since they are always active), others
|
|||
|
|
(ie idle objects) have no need to maintain a status word, since whenever they are active, they are ready to
|
|||
|
|
deliver an event.
|
|||
|
|
|
|||
|
|
|
|||
|
|
One drawback of continuous activity
|
|||
|
|
|
|||
|
|
|
|||
|
|
Interestingly, Events4 has re-introduced the "stay awake" bug that Events2 managed to fix from Events.
|
|||
|
|
This fact can easily be verified by user experimentation.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The call make to p_unmarka is now ineffective since, as is explained in the Plib Reference manual
|
|||
|
|
(section on p_unmarka), it is the sys$null process which administers the auto-switch-off, yet it will have no
|
|||
|
|
opportunity to run if any other applications are continually running. The point is that the priority of
|
|||
|
|
sys$null is lower than that of any other process.
|
|||
|
|
|
|||
|
|
|
|||
|
|
One possible solution here is to call, say, p_sleept (2) every so often, to try to allow sys$null to run.
|
|||
|
|
However, this too will fail in the rare case when there are two similarly anti-social applications running
|
|||
|
|
simultaneously on the SIBO computer. Even if they both call p_sleept periodically, there is little chance
|
|||
|
|
of them both sleeping at the same time - which would be required in order for sys$null to run.
|
|||
|
|
|
|||
|
|
|
|||
|
|
A better solution is to call p_allowoff from time to time. By doing so an application assumes
|
|||
|
|
responsibility for performing the auto-switch-off that would otherwise be done by sys$null if it had an
|
|||
|
|
opportunity to run.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Remarks on process priorities
|
|||
|
|
|
|||
|
|
|
|||
|
|
The above problem of preventing the SIBO computer from auto-switching off is not the only potentially
|
|||
|
|
deleterious side-effect of continuous activity. Just as continuous activity within Events4 prevents sys$null
|
|||
|
|
receiving any CPU, so too will any other lower priority processes be locked out.
|
|||
|
|
|
|||
|
|
|
|||
|
|
As it happens, Subproc and Events4 both run at the same process priority - the default of 0x80. (See the
|
|||
|
|
chapter Building an Application for details on how process priorities are initialised.) However, suppose
|
|||
|
|
the process priority of Subproc were lowered to say 0x70. In that case, continuous activity within Events4
|
|||
|
|
would mean that Subproc, although launched, would never receive any CPU. Thus Events4 would
|
|||
|
|
perpetually display the message "Subp launched", but never the completion message "Subp slept xxx
|
|||
|
|
ticks".
|
|||
|
|
|
|||
|
|
|
|||
|
|
The solution here is that any process about to become computationally intensive over a long period of time
|
|||
|
|
should consider lowering its process priority, say to 0x70 - using the call p_setpri. For some related
|
|||
|
|
discussion, see the section on wStartCompute in the Window Server Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-14
|
|||
|
|
|
|||
|
|
|
|||
|
|
5 FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
The call p_ioyield
|
|||
|
|
|
|||
|
|
|
|||
|
|
One more potentially surprising fact about continuous activity within a program ought to be mentioned.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Clearly, not every program needs to be structured with an asynchronous event processing loop as in the
|
|||
|
|
Events programs. Whilst such a loop is undoubtedly the correct architecture for a larger program, other
|
|||
|
|
simple programs may have alternative structures.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For example, Subproc makes no call to p_iowait - nor does it need to, being purely single-threaded.
|
|||
|
|
Again, the example Plib programs discussed in the chapter Building an Application (eg p_hello, p_comp
|
|||
|
|
and p_prndir) likewise survive without an asynchronous event processing loop, since they are likewise
|
|||
|
|
single-threaded.
|
|||
|
|
|
|||
|
|
|
|||
|
|
However, there may be a temptation for programs to use the following semi-asynchronous mechanism, in
|
|||
|
|
order to be able to respond to keypresses (say) whilst being mainly dedicated to some continuous activity:
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ continue processing queue an asynchronous request to receive a keypress
|
|||
|
|
e start the continuous activity
|
|||
|
|
e every so often, test to see if the status word is still z_F1LE_PENDING
|
|||
|
|
e if it is, continue processing
|
|||
|
|
In other words:
|
|||
|
|
|
|||
|
|
|
|||
|
|
FOREVER
|
|||
|
|
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
QueueSer (&keystat) ;
|
|||
|
|
|
|||
|
|
while (keystat==E_FILE_PENDING)
|
|||
|
|
MoreProcessing();
|
|||
|
|
|
|||
|
|
ProcessKey();
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
However, this program may totally fail, with keystat never changing from B_FILE_PENDING.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The reason for this is rather complicated, but it is worth understanding. It has to do with what happens
|
|||
|
|
when an asynchronous event completes. This completion often involves two distinct phases:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the completion itself happens on an interrupt
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ an interrupt service routine runs, and the i/o device changes some of its internal variables to
|
|||
|
|
record this fact
|
|||
|
|
|
|||
|
|
|
|||
|
|
e however, the i/o device generally cannot write to the associated status word during the interrupt
|
|||
|
|
service routine itself
|
|||
|
|
|
|||
|
|
|
|||
|
|
e this is because there are strict rules on what can and cannot be done within an interrupt service
|
|||
|
|
routine (see the chapter Writing Device Drivers in the Additional System Information manual for
|
|||
|
|
more details)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e instead, the i/o device relies upon its so-called wait handler routine to be called, so that it can
|
|||
|
|
finish the job of completing the request - writing to the status word and signalling the application
|
|||
|
|
|
|||
|
|
|
|||
|
|
e these wait handler routines only have an opportunity to run inside the call p_iowait (or
|
|||
|
|
equivalent).
|
|||
|
|
|
|||
|
|
|
|||
|
|
In other words, the description given earlier in this chapter of the functioning of p_iowait was incomplete
|
|||
|
|
in one important respect: not only does this routine take note of the value of the i/o semaphore for the
|
|||
|
|
application, and suspend the application so long as this remains negative; it also gives all i/o device
|
|||
|
|
channels in the application an opportunity to run their wait handlers.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-15
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
Accordingly, the earlier code has to be changed into
|
|||
|
|
|
|||
|
|
|
|||
|
|
FOREVER
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
QueueSer (&keystat) ;
|
|||
|
|
|
|||
|
|
while (keystat==E_FILE_PENDING)
|
|||
|
|
{
|
|||
|
|
MoreProcessing();
|
|||
|
|
p_iosignal();
|
|||
|
|
p_iowait ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
ProcessKey ();
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
which is in fact much more in line with the main routine of the Events4 application discussed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For convenience, the single call p_ioyie1d can be used with the same effect as p_iosignal followed by
|
|||
|
|
|
|||
|
|
|
|||
|
|
p_iowait.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note incidentally that it is a rare application that needs to actually write a wait handler; there is of course
|
|||
|
|
no need to write a wait handler routine just because an application involves asynchronous i/o.
|
|||
|
|
|
|||
|
|
|
|||
|
|
General remarks
|
|||
|
|
|
|||
|
|
|
|||
|
|
Multi-threadedness and multi-tasking
|
|||
|
|
|
|||
|
|
|
|||
|
|
For the sake of clarity, the two different notions of multi-tasking and multi-threadedness ought to be
|
|||
|
|
compared and contrasted:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e multi-tasking involves two (or more) different processes; multi-threadedness involves two (or
|
|||
|
|
more) event sources within one process
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the operating system takes care of multi-tasking automatically, on behalf of applications; multi-
|
|||
|
|
threadedness requires conscious effort from an application
|
|||
|
|
|
|||
|
|
|
|||
|
|
e §=multi-tasking is pre-emptive in that a process with a higher priority that is ready to run will
|
|||
|
|
always displace a lower priority process that is running
|
|||
|
|
|
|||
|
|
|
|||
|
|
e multi-threadedness is non pre-emptive in that an event source with a higher priority has to wait
|
|||
|
|
until a lower priority event source voluntarily gives up CPU, before being able to run.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Subprocess or idle object?
|
|||
|
|
|
|||
|
|
|
|||
|
|
In the design of large systems, there is considerable scope for decision-making on whether to assign
|
|||
|
|
compute-intensive tasks to idle objects within an application, or to a subprocess of the application proper.
|
|||
|
|
Some factors that may be considered in making such a decision are:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e having two different processes automatically allows a total combined dataspace greater than 64k
|
|||
|
|
|
|||
|
|
|
|||
|
|
e asubprocess need not worry unduly about creating "holes" ("fragmentation") in its allocator
|
|||
|
|
heap, since these will all vanish when the subprocess terminates (when its entire heap vanishes);
|
|||
|
|
however, if an idle object is transient and terminates well before the overall application finishes,
|
|||
|
|
any fragmentation it creates in the allocator heap may have a more damaging long-term effect
|
|||
|
|
(see the chapter Memory Allocation in the Plib Reference manual)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e an idle object is much more tightly bound to the main program than is a subprocess
|
|||
|
|
|
|||
|
|
|
|||
|
|
¢ communications between a subprocess and the main program have to be much more formalised
|
|||
|
|
than is the case with an idle object
|
|||
|
|
|
|||
|
|
|
|||
|
|
e an idle object can draw to the same windows on the screen as the main application, but not so for
|
|||
|
|
a subprocess (except in the case of the MC - see the function wAttachToclient in the Window
|
|||
|
|
Server Reference manual).
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-16
|
|||
|
|
|
|||
|
|
|
|||
|
|
5 FUNDAMENTAL PROGRAMMING GUIDE-LINES
|
|||
|
|
|
|||
|
|
|
|||
|
|
Window redraws as an event source
|
|||
|
|
|
|||
|
|
|
|||
|
|
Up till now, one very important event source has not been mentioned in this chapter. This is the event of a
|
|||
|
|
window requesting itself to be redrawn. (In fact, the request originates from the Window Server.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
These events do not occur when using console i/o, nor when using windows with back-up bitmaps:
|
|||
|
|
windows are automatically redrawn by the Window Server in these cases. However, high quality
|
|||
|
|
applications undertake window redrawing by themselves, so as to avoid the large ram overheads of the
|
|||
|
|
back-up bitmaps. (See the Introduction chapter of the Window Server Reference manual.)
|
|||
|
|
|
|||
|
|
|
|||
|
|
Such applications must remain responsive to redraw events at all times - otherwise their screen will
|
|||
|
|
remain blank if they are suddenly task switched into foreground, or if an overlapping menu or dialog
|
|||
|
|
window is removed. This is all the more reason for these applications to adopt the sort of general event
|
|||
|
|
processing architecture outlined in this chapter.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The APPMAN and ACTIVE classes in OLIB
|
|||
|
|
|
|||
|
|
|
|||
|
|
The appman and active classes in olib.dyl provide system support for object-oriented applications
|
|||
|
|
e representing their event sources (each event source is represented by an "active object")
|
|||
|
|
e prioritising these event sources
|
|||
|
|
¢ maintaining active and status words for each event source
|
|||
|
|
e calling p_iowait at appropriate times
|
|||
|
|
e ensuring that all event sources are properly polled.
|
|||
|
|
|
|||
|
|
|
|||
|
|
At the same time, the appman class ("appman" is short for "application manager") provides an automated
|
|||
|
|
mechanism for error handling, as well as handling the interface to resource files (see the Resource Files
|
|||
|
|
chapter in the Additional System Information manual).
|
|||
|
|
|
|||
|
|
|
|||
|
|
These topics are further discussed in the Object Oriented Programming Guide. In addition, the appman
|
|||
|
|
and active classes are documented in the OLIB Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-17
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
5-18
|
|||
|
|
|
|||
|
|
|
|||
|
|
CHAPTER 6
|
|||
|
|
|
|||
|
|
|
|||
|
|
CoPyY-PROTECTING SOFTWARE
|
|||
|
|
|
|||
|
|
|
|||
|
|
Introduction
|
|||
|
|
|
|||
|
|
|
|||
|
|
This chapter considers various mechanisms to "copy-protect" software written for SIBO computers.
|
|||
|
|
Possible goals of copy-protection include:
|
|||
|
|
|
|||
|
|
e software should be able to run, only from the original SSD it is supplied in
|
|||
|
|
|
|||
|
|
e — software should be able to run, only on one particular computer
|
|||
|
|
|
|||
|
|
|
|||
|
|
e first generation copies should be allowed, but not second generation copies (ie direct copies make
|
|||
|
|
from the original SSD would run, but not copies of these copies)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e possibly, the number of first generation copies allowed could be limited.
|
|||
|
|
|
|||
|
|
|
|||
|
|
These different goals vary in their applicability to the different computers in the SIBO range. For
|
|||
|
|
example, software that disallowed even first generation copies would be very unwelcome on the Series 3,
|
|||
|
|
because it prevents consolidation - the process whereby users copy more than one different application
|
|||
|
|
onto the same SSD. It is unlikely that such software would sell at all well. On the other hand, this kind of
|
|||
|
|
strict copy protection makes more sense for the HC, and for corporate ("Vertical") programs generally.
|
|||
|
|
|
|||
|
|
|
|||
|
|
At the same time, software developers may wish to apply differing amounts of sophistication in their copy
|
|||
|
|
protection schemes - some being willing merely to frustrate the casual would-be copier, and some being
|
|||
|
|
determined not to allow copying at all (if possible).
|
|||
|
|
|
|||
|
|
|
|||
|
|
This chapter does not favour one copy protection method over all others. Rather, it simply hints at various
|
|||
|
|
different possibilities. Software developers may find it convenient to mix and match the different
|
|||
|
|
proposals made, as well as others (along the same lines) that they can think of themselves.
|
|||
|
|
|
|||
|
|
|
|||
|
|
By the very nature of the subject, too much documentation would be self-defeating. Once any algorithm to
|
|||
|
|
implement copy protection becomes widely known, methods to defeat this algorithm may be developed
|
|||
|
|
and circulated.
|
|||
|
|
|
|||
|
|
|
|||
|
|
| ic I a
|
|||
|
|
The free space method
|
|||
|
|
|
|||
|
|
|
|||
|
|
This method aims at strict copy protection: the software will only run if it is on the original SSD.
|
|||
|
|
|
|||
|
|
|
|||
|
|
This simple yet effective method turns one of the commonly debated ‘disadvantages’ of using Flash storage
|
|||
|
|
into an advantage.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The method is based around the fact that when a file is deleted from a Flash SSD it remains on the pack
|
|||
|
|
taking up space but is no longer practically accessible. Assuming that an application master pack contains
|
|||
|
|
a deleted file, if someone were to copy this pack using the usual copy from the root including
|
|||
|
|
subdirectories, the resulting copy of the master pack will differ fundamentally: the deleted file no longer
|
|||
|
|
exists. This in turn means, rather conveniently, that the amount of free space on the pack will be different.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Given the above you can then hard-code into your application a check to see if the figure for space on the
|
|||
|
|
pack matches the figure you expect: if it does then all well and good; else, do not allow the software to
|
|||
|
|
run.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
The way to find the amount of free space on an SSD is to call p_dinfo. For example, a program that prints
|
|||
|
|
the amount of free space on the disk the program was launched from:
|
|||
|
|
|
|||
|
|
|
|||
|
|
#include <p_std.h>
|
|||
|
|
#include <p_file.h>
|
|||
|
|
#include <p_sys.h>
|
|||
|
|
|
|||
|
|
|
|||
|
|
GLREF_D TEXT *DatCommandPtr;
|
|||
|
|
|
|||
|
|
|
|||
|
|
GLDEF_C INT main(VOID)
|
|||
|
|
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
P_DINFO dinfo;
|
|||
|
|
|
|||
|
|
|
|||
|
|
p_dinfo(DatCommandPtr, &édinfo) ;
|
|||
|
|
|
|||
|
|
p_printf ("Free space is %lu",dinfo.free);
|
|||
|
|
p_getch ();
|
|||
|
|
|
|||
|
|
return (0);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
First generation copying methods
|
|||
|
|
|
|||
|
|
|
|||
|
|
Methods that allow first generation copies to run, but not second generation copies, rely on a separate
|
|||
|
|
"AppCopy" program being provided on the master SSD, in addition to the program itself.
|
|||
|
|
|
|||
|
|
|
|||
|
|
First generation copies can only be made using the AppCopy program. Copies made using ordinary Copy
|
|||
|
|
commands will fail. Further, AppCopy will refuse to copy first generation copies into second generation
|
|||
|
|
copies.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Essentially, AppCopy does not make an exact copy, but changes some of the bytes in the application
|
|||
|
|
program. This can be done, even on Flash SSDs, provided:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the original values of the bytes are all oxrft's
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the bytes are adjusted one at a time (assuming that a complete copy has already been made, and
|
|||
|
|
that this complete copy has to be altered).
|
|||
|
|
|
|||
|
|
|
|||
|
|
The last point is most important; the Flash filing system tests for the special case of only one byte being
|
|||
|
|
written, and in this case, alters the physical byte on the SSD. In other cases, the physical structure of the
|
|||
|
|
file is significantly changed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Preserving checksums
|
|||
|
|
|
|||
|
|
|
|||
|
|
Note that in adjusting bytes in a program file, care has to be taken not to disturb the code or data
|
|||
|
|
checksums (as reported eg by the tool edump.exe). Otherwise, the operating system will refuse to run the
|
|||
|
|
program, believing it to be corrupt.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The checksums can be preserved in either of two ways:
|
|||
|
|
e provided enough bytes are changed, the checksum can be left the same as it was originally
|
|||
|
|
|
|||
|
|
|
|||
|
|
e rather than changing the program part of the image file, one of the add-files inside the image file
|
|||
|
|
should be changed (see the chapter Building an Application for details of add-files).
|
|||
|
|
|
|||
|
|
|
|||
|
|
In general, the second method is preferable.
|
|||
|
|
What kind of change should be made
|
|||
|
|
The change made to the program file has two purposes:
|
|||
|
|
e the file is now recognisably a first generation copy
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the change contains data somehow allowing this first generation copy to run, in a way preventing
|
|||
|
|
a straight copy of this file from running on another computer.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Possible ideas on this second point include:
|
|||
|
|
|
|||
|
|
|
|||
|
|
e information from an environment variable specially created on the target computer (secretly and
|
|||
|
|
with a random value), by the AppCopy program
|
|||
|
|
|
|||
|
|
|
|||
|
|
e the date the copy was made (so that the copy will "expire" after a certain length of time)
|
|||
|
|
|
|||
|
|
|
|||
|
|
e details about the low-level structure of the SSD (see below).
|
|||
|
|
|
|||
|
|
|
|||
|
|
6 COPY-PROTECTING SOFTWARE
|
|||
|
|
|
|||
|
|
|
|||
|
|
To make the mechanism less obvious to a casual browser, any information from say an environment
|
|||
|
|
variable ought to be stored in the file encrypted in some way.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Restricting the number of copies made
|
|||
|
|
|
|||
|
|
|
|||
|
|
In order to restrict the number of first generation copies ever made to eight, say (which would not be
|
|||
|
|
unreasonable), certain bytes in the master copy of the program could be changed. As above, these bytes
|
|||
|
|
would start with the value oxf£, and would have to be written one at a time.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The documentation for the product would have to state clearly that AppCopy could only be used eight
|
|||
|
|
times. This would have the effect of making the owner of the software most wary against making cavalier
|
|||
|
|
bootleg copies.
|
|||
|
|
|
|||
|
|
|
|||
|
|
This method will of course only work if the SSD containing the original copy can be written to. This will
|
|||
|
|
be impossible for OTP (One Time Programmable) or masked ROM SSDs. In this case, information about
|
|||
|
|
the number of first generation copies made could be stored in another environment variable, though of
|
|||
|
|
course this method would be easier to subvert.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Low level SSD information
|
|||
|
|
|
|||
|
|
|
|||
|
|
Each SSD contains a so-called "unique ID" which can be used to identify it.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Another potentially very useful piece of information would be the physical pack offset of the start of a
|
|||
|
|
nominated file on an SSD. An AppCopy program could create a small file on the target SSD, and then
|
|||
|
|
delete it, before copying the program file across. The physical pack offset of the start of the program file
|
|||
|
|
could then be written into the program file (possibly in encrypted form), for the program to check when it
|
|||
|
|
starts to run.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Alternatively, information could be read from the deleted file.
|
|||
|
|
|
|||
|
|
|
|||
|
|
These types of information can be read by use of the p_locreadpda function, described in the Files
|
|||
|
|
chapter of the PLIB Reference manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Copy-protection by changing the ROM
|
|||
|
|
|
|||
|
|
|
|||
|
|
In the case of the HC, it is possible to use the tool romwrite.exe to overwrite portions of a file custom$.dat
|
|||
|
|
in the ROM of the HC. See the chapter Introduction to the HC in the HC Programming Guide for details
|
|||
|
|
of the operation of romwrite.exe.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Programs can then check that they are running on a given specified HC.
|
|||
|
|
|
|||
|
|
|
|||
|
|
To read the contents of custom$.dat, just open the file as normal, specifying the full path name
|
|||
|
|
rom: :custom$.dat.
|
|||
|
|
|
|||
|
|
|
|||
|
|
One other possibility is to change the contents of the ROM more radically, eg placing certain software into
|
|||
|
|
the ROM, with a program on an SSD refusing to run unless this software is present in the ROM. For more
|
|||
|
|
details, again see the HC Programming Guide.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
6-4
|
|||
|
|
|
|||
|
|
|
|||
|
|
CHAPTER 7
|
|||
|
|
|
|||
|
|
|
|||
|
|
COMPATIBILITY
|
|||
|
|
|
|||
|
|
|
|||
|
|
Introduction
|
|||
|
|
|
|||
|
|
|
|||
|
|
The vast majority of existing software will, in principle, run on all machines in the SIBO range, provided
|
|||
|
|
that the display can accommodate itself to the different screen sizes.
|
|||
|
|
|
|||
|
|
|
|||
|
|
For details of the differences between SIBO machines see Writing Software for the HC in the HC
|
|||
|
|
Programming Guide and the Series 3 family compatibility section of the Series 3 Programming Overview
|
|||
|
|
chapter in the Series 3/3a Programming Guide manual.
|
|||
|
|
|
|||
|
|
|
|||
|
|
What machine am I running on?
|
|||
|
|
|
|||
|
|
|
|||
|
|
Most SIBO machines can be distinguished by their screen sizes, as determined by the return value from a
|
|||
|
|
call to p_geticda. The possible return values for existing SIBO machines are as follows:
|
|||
|
|
|
|||
|
|
|
|||
|
|
E_LCD_640_400 (0)
|
|||
|
|
E_LCD_640_200_SMALL (1)
|
|||
|
|
E_LCD_160_80 (4)
|
|||
|
|
E_LCD_240_80 (5)
|
|||
|
|
E_LCD_480_160 (11)
|
|||
|
|
E_LCD_240_100 (12)
|
|||
|
|
E_LCD_240_160 (14)
|
|||
|
|
|
|||
|
|
|
|||
|
|
a 640x400 pixel display as on the MC 400
|
|||
|
|
|
|||
|
|
a 640x200 pixel display as on the MC 200
|
|||
|
|
|
|||
|
|
a 160x80 pixel display as on the HC
|
|||
|
|
|
|||
|
|
a 240x80 pixel display as on the Series 3
|
|||
|
|
|
|||
|
|
a 480x160 pixel display as on the Series 3a and Series 3c
|
|||
|
|
a 240x100 pixel display as on the Workabout
|
|||
|
|
|
|||
|
|
a 240x160 pixel display, as on the Siena
|
|||
|
|
|
|||
|
|
|
|||
|
|
This will distinguish all machines except the Series 3a and Series 3c, which have screens of the same size.
|
|||
|
|
These two machines can be distinguished by means of a call to the function p_returnexpansionportinfo,
|
|||
|
|
present in machines with EPOC version 3.90F or later, as in the following example code fragment.
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
UINT lcdtype;
|
|||
|
|
UINT version;
|
|||
|
|
UINT port;
|
|||
|
|
|
|||
|
|
|
|||
|
|
lcdtype=p_getlcd();
|
|||
|
|
|
|||
|
|
if (lcdtype==E_LCD_480_160)
|
|||
|
|
{ /* S3a or S3c */
|
|||
|
|
version=p_version();
|
|||
|
|
if (version>=0x390F)
|
|||
|
|
|
|||
|
|
|
|||
|
|
{ /* safe to call p_returnexpansionportinfo */
|
|||
|
|
|
|||
|
|
|
|||
|
|
port=p_returnexpansionportinfo()
|
|||
|
|
if ((port & 0x0700)==0x0300)
|
|||
|
|
{
|
|||
|
|
/* must be S3c */
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/* must be S3a */
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/* EPOC version less than 3.90,
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/* machine determined by LCD type */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
’
|
|||
|
|
|
|||
|
|
|
|||
|
|
so must be S3a */
|
|||
|
|
|
|||
|
|
|
|||
|
|
INDEX
|
|||
|
|
|
|||
|
|
|
|||
|
|
.afl files
|
|||
|
|
|
|||
|
|
add file lists, 3-13
|
|||
|
|
|
|||
|
|
add file lists - changing, 3-14
|
|||
|
|
.app files
|
|||
|
|
|
|||
|
|
versus .img files, 3-13
|
|||
|
|
.dfl files
|
|||
|
|
|
|||
|
|
add file lists for DYLs, 3-14
|
|||
|
|
.dyl files
|
|||
|
|
|
|||
|
|
building with emake.exe, 3-14
|
|||
|
|
.img files
|
|||
|
|
|
|||
|
|
applications, 3-1
|
|||
|
|
|
|||
|
|
control over, 3-12
|
|||
|
|
|
|||
|
|
creating, 3-3
|
|||
|
|
|
|||
|
|
versus .app files, 3-13
|
|||
|
|
Idd files
|
|||
|
|
|
|||
|
|
building with emake.exe, 3-14
|
|||
|
|
.pdd files
|
|||
|
|
|
|||
|
|
building with emake.exe, 3-14
|
|||
|
|
.pic files
|
|||
|
|
|
|||
|
|
application icons, 3-13
|
|||
|
|
.pr files
|
|||
|
|
|
|||
|
|
application project files, 3-1
|
|||
|
|
|
|||
|
|
project files - a first look, 3-2
|
|||
|
|
sc files
|
|||
|
|
|
|||
|
|
resource files - application, 3-13
|
|||
|
|
zc files
|
|||
|
|
|
|||
|
|
resource files compressed, 3-13
|
|||
|
|
.shd files
|
|||
|
|
|
|||
|
|
shell data files, 3-13
|
|||
|
|
ACTIVE class
|
|||
|
|
|
|||
|
|
remarks on OLIB, 5-16
|
|||
|
|
add file list
|
|||
|
|
|
|||
|
|
application, 3-13
|
|||
|
|
|
|||
|
|
application - changing, 3-14
|
|||
|
|
|
|||
|
|
application DYLs, 3-14
|
|||
|
|
application
|
|||
|
|
|
|||
|
|
a first look at .img files, 3-3
|
|||
|
|
|
|||
|
|
add file lists, 3-13
|
|||
|
|
|
|||
|
|
add file lists - changing, 3-14
|
|||
|
|
|
|||
|
|
add file lists for DYLs, 3-14
|
|||
|
|
|
|||
|
|
app files vs img files, 3-13
|
|||
|
|
|
|||
|
|
batch files - housekeeping, 3-6
|
|||
|
|
|
|||
|
|
building, 3-1
|
|||
|
|
|
|||
|
|
building - introduction, 3-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
building - more complex example, 3-9
|
|||
|
|
building - more complex example PLIB, 3-9
|
|||
|
|
|
|||
|
|
|
|||
|
|
building - multi-file, 3-9
|
|||
|
|
building - with assembler, 3-11
|
|||
|
|
building emake.exe, 3-14
|
|||
|
|
building eremake.exe, 3-14
|
|||
|
|
|
|||
|
|
|
|||
|
|
copy protection see copy protection, 6-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
debugging on SIBO system, 3-4
|
|||
|
|
file - control over, 3-12
|
|||
|
|
file transfer to SIBO system, 3-1, 3-3
|
|||
|
|
graphics and, 3-10
|
|||
|
|
heap size - minimum, 3-12
|
|||
|
|
Hwif - building, 3-10
|
|||
|
|
icon files, 3-13
|
|||
|
|
information from edump.exe, 3-12
|
|||
|
|
multi-tasking - remarks on, 5-16
|
|||
|
|
multi-threaded - remarks on, 5-16
|
|||
|
|
priority - control over, 3-12
|
|||
|
|
resource .rsc files, 3-13
|
|||
|
|
resource files .rzc compressed, 3-13
|
|||
|
|
running on SIBO system, 3-3
|
|||
|
|
shell data files, 3-13
|
|||
|
|
version number - control over, 3-12
|
|||
|
|
application development
|
|||
|
|
C SDK equipment required, 3-1
|
|||
|
|
C SDK files for oop, 3-2
|
|||
|
|
C SDK files required, 3-2
|
|||
|
|
first example, 3-2
|
|||
|
|
fundamental guide-lines, 5-1
|
|||
|
|
applications
|
|||
|
|
.img files, 3-1
|
|||
|
|
APPMAN class
|
|||
|
|
remarks on OLIB, 5-16
|
|||
|
|
assembler
|
|||
|
|
applications - containing, 3-11
|
|||
|
|
asynchronous I/O
|
|||
|
|
programming, 5-2
|
|||
|
|
auto-switch-off
|
|||
|
|
p_unmarka, 5-14
|
|||
|
|
SYS$NULL - chance to run, 5-14
|
|||
|
|
background processing
|
|||
|
|
programming example, 5-2
|
|||
|
|
batch files
|
|||
|
|
application housekeeping, 3-6
|
|||
|
|
compilation, 3-6
|
|||
|
|
compilation complications, 3-7
|
|||
|
|
build
|
|||
|
|
C SDK configuration files, 3-11
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
building
|
|||
|
|
|
|||
|
|
|
|||
|
|
C
|
|||
|
|
|
|||
|
|
|
|||
|
|
applications, 3-1
|
|||
|
|
|
|||
|
|
applications - control over, 3-12
|
|||
|
|
applications - more complex example, 3-9
|
|||
|
|
applications - more complex example PLIB,
|
|||
|
|
3-9
|
|||
|
|
|
|||
|
|
applications - multi-file, 3-9
|
|||
|
|
|
|||
|
|
applications - with assembler, 3-11
|
|||
|
|
applications introduction, 3-1
|
|||
|
|
|
|||
|
|
applications with graphics, 3-10
|
|||
|
|
applications with Hwif, 3-10
|
|||
|
|
|
|||
|
|
|
|||
|
|
manuals - Topspeed C, 2-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
C SDK
|
|||
|
|
|
|||
|
|
|
|||
|
|
C++
|
|||
|
|
|
|||
|
|
|
|||
|
|
build configuration files, 3-11
|
|||
|
|
|
|||
|
|
configuration file tscfg compiler, 3-11
|
|||
|
|
configuration file tsprj.txt, 3-11
|
|||
|
|
|
|||
|
|
configuring the redirection file, 1-3
|
|||
|
|
configuring the Topspeed project system, 1-
|
|||
|
|
2
|
|||
|
|
|
|||
|
|
|
|||
|
|
directory structure, 1-2
|
|||
|
|
documentation version, 1-1
|
|||
|
|
equipment required, 3-1
|
|||
|
|
files required, 3-2
|
|||
|
|
|
|||
|
|
files required - oop, 3-2
|
|||
|
|
installation, 1-1
|
|||
|
|
installation phases, 1-1
|
|||
|
|
manuals, 2-1
|
|||
|
|
|
|||
|
|
manuals - where to start, 2-2
|
|||
|
|
overview SIBO system, 2-1
|
|||
|
|
professional version, 1-1
|
|||
|
|
SIBO software, 1-2
|
|||
|
|
|
|||
|
|
small model code, 1-1
|
|||
|
|
standard version, 1-1
|
|||
|
|
Topspeed C, 1-1
|
|||
|
|
|
|||
|
|
Topspeed software, 1-2
|
|||
|
|
variants of, 1-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
object oriented programming and, 2-3
|
|||
|
|
|
|||
|
|
|
|||
|
|
cancelling timers
|
|||
|
|
|
|||
|
|
|
|||
|
|
in general, 5-6
|
|||
|
|
|
|||
|
|
|
|||
|
|
Clarion Software
|
|||
|
|
|
|||
|
|
|
|||
|
|
Topspeed C, 1-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
CLIB
|
|||
|
|
|
|||
|
|
|
|||
|
|
console device I/O, 4-3
|
|||
|
|
|
|||
|
|
DOS file names, 4-3
|
|||
|
|
|
|||
|
|
file handle conversion, 4-2
|
|||
|
|
|
|||
|
|
floating point emulator, 4-3
|
|||
|
|
|
|||
|
|
floating point emulator - panic 80, 4-3
|
|||
|
|
int86x implementation, 4-2
|
|||
|
|
|
|||
|
|
intr implementation, 4-2
|
|||
|
|
|
|||
|
|
library - building, 4-4
|
|||
|
|
|
|||
|
|
missing DOS functions, 4-1
|
|||
|
|
|
|||
|
|
notes on, 4-1
|
|||
|
|
|
|||
|
|
|
|||
|
|
CLIB & PLIB
|
|||
|
|
|
|||
|
|
|
|||
|
|
contrasted, 3-4
|
|||
|
|
|
|||
|
|
|
|||
|
|
code size
|
|||
|
|
application CLIB, 3-5
|
|||
|
|
application PLIB, 3-5
|
|||
|
|
compatibility
|
|||
|
|
software on SIBO systems, 7-1
|
|||
|
|
compilation
|
|||
|
|
batch file complications, 3-7
|
|||
|
|
batch files, 3-6
|
|||
|
|
optimisation warning, 3-11
|
|||
|
|
TSC vs TSCX, 3-8
|
|||
|
|
compute intensive application
|
|||
|
|
CPU yielding, 5-13
|
|||
|
|
configuration file
|
|||
|
|
C SDK tscfg compiler, 3-11
|
|||
|
|
C SDK tsprj.txt, 3-11
|
|||
|
|
configuration files
|
|||
|
|
C SDK build, 3-11
|
|||
|
|
console device
|
|||
|
|
implementation in CLIB, 4-3
|
|||
|
|
in general, 5-6
|
|||
|
|
cooperating applications
|
|||
|
|
debugging, 5-11
|
|||
|
|
copy protection
|
|||
|
|
first generation copy method, 6-2
|
|||
|
|
free space method, 6-1
|
|||
|
|
introduction, 6-1
|
|||
|
|
low level SSD method, 6-3
|
|||
|
|
mechanisms, 6-1
|
|||
|
|
ROM changing method, 6-3
|
|||
|
|
CPU intensive
|
|||
|
|
yielding in applications, 5-13
|
|||
|
|
CPU yielding
|
|||
|
|
compute intensive applications, 5-13
|
|||
|
|
programming, 5-2
|
|||
|
|
customised
|
|||
|
|
libraries, 3-10
|
|||
|
|
debugging
|
|||
|
|
applications - on SIBO system, 3-1, 3-4
|
|||
|
|
cooperating applications, 5-11
|
|||
|
|
serial port comms applications, 5-13
|
|||
|
|
device driver
|
|||
|
|
LDD - building with emake.exe, 3-14
|
|||
|
|
PDD - building with emake.exe, 3-14
|
|||
|
|
devices
|
|||
|
|
I/O in general, 5-5
|
|||
|
|
directory structure
|
|||
|
|
C SDK, 1-2
|
|||
|
|
documentation
|
|||
|
|
C SDK - where to start, 2-2
|
|||
|
|
documentation sources
|
|||
|
|
programming, 5-1
|
|||
|
|
DOS functions
|
|||
|
|
CLIB - missing functions, 4-1
|
|||
|
|
DYL
|
|||
|
|
add file lists into application, 3-14
|
|||
|
|
building with emake.exe, 3-14
|
|||
|
|
dynamic library
|
|||
|
|
DYL - building with emake.exe, 3-14
|
|||
|
|
|
|||
|
|
|
|||
|
|
edump.exe
|
|||
|
|
application information, 3-12
|
|||
|
|
utility program, 3-12
|
|||
|
|
emake.exe
|
|||
|
|
application building, 3-14
|
|||
|
|
application conversion, 3-1
|
|||
|
|
utility program, 3-14
|
|||
|
|
EPOC
|
|||
|
|
explained, 2-2
|
|||
|
|
epocinit
|
|||
|
|
project file statement, 3-6
|
|||
|
|
eremake.exe
|
|||
|
|
application building, 3-14
|
|||
|
|
utility program, 3-14
|
|||
|
|
error handling
|
|||
|
|
a first look, 5-7
|
|||
|
|
events and, 5-7
|
|||
|
|
resource tidying, 5-8
|
|||
|
|
errors
|
|||
|
|
panic number ranges, 2-3
|
|||
|
|
panics explained, 2-3
|
|||
|
|
events
|
|||
|
|
active and inactive sources, 5-12
|
|||
|
|
ACTIVE class - remarks on, 5-16
|
|||
|
|
APPMAN class - remarks on, 5-16
|
|||
|
|
idle objects, 5-14
|
|||
|
|
multiple source examples, 5-3
|
|||
|
|
p_iosignal - function of, 5-14
|
|||
|
|
prioritisation of sources, 5-5
|
|||
|
|
window redraw - remarks on, 5-16
|
|||
|
|
example code
|
|||
|
|
detecting which SIBO system, 7-1
|
|||
|
|
fatal program errors
|
|||
|
|
panics explained, 2-3
|
|||
|
|
file handle
|
|||
|
|
conversion in CLIB, 4-2
|
|||
|
|
file names
|
|||
|
|
DOS implementation in CLIB, 4-3
|
|||
|
|
file transfer
|
|||
|
|
applications - to SIBO system, 3-1
|
|||
|
|
applications to SIBO system, 3-3
|
|||
|
|
floating point
|
|||
|
|
emulator - panic 80 in CLIB, 4-3
|
|||
|
|
emulator in CLIB, 4-3
|
|||
|
|
fundamental guide-lines
|
|||
|
|
programming, 5-1
|
|||
|
|
graphics
|
|||
|
|
applications and, 3-10
|
|||
|
|
heap size
|
|||
|
|
minimum, 3-12
|
|||
|
|
hello world
|
|||
|
|
application - PLIB first example, 3-4
|
|||
|
|
application first example, 3-2
|
|||
|
|
Hwif
|
|||
|
|
application building, 3-10
|
|||
|
|
I/O devices
|
|||
|
|
in general, 5-5
|
|||
|
|
|
|||
|
|
|
|||
|
|
INDEX
|
|||
|
|
|
|||
|
|
|
|||
|
|
icon files
|
|||
|
|
application, 3-13
|
|||
|
|
IDE
|
|||
|
|
Topspeed Integrated Development
|
|||
|
|
Environment, 3-1
|
|||
|
|
idle object
|
|||
|
|
contrasted with sub-process, 5-16
|
|||
|
|
idle objects
|
|||
|
|
events, 5-14
|
|||
|
|
p_iosignal - function of, 5-14
|
|||
|
|
image file
|
|||
|
|
control over, 3-12
|
|||
|
|
include file
|
|||
|
|
stdepoc.h, 3-11
|
|||
|
|
installation
|
|||
|
|
C SDK, 1-1
|
|||
|
|
int86x
|
|||
|
|
implementation in CLIB, 4-2
|
|||
|
|
inter-process communications
|
|||
|
|
in Events2 - and Subproc, 5-8
|
|||
|
|
mechanisms, 5-10
|
|||
|
|
intr
|
|||
|
|
implementation in CLIB, 4-2
|
|||
|
|
IPCS
|
|||
|
|
in Events2 - and Subproc, 5-8
|
|||
|
|
mechanisms, 5-10
|
|||
|
|
key presses
|
|||
|
|
remarks on, 5-4
|
|||
|
|
keyboard input
|
|||
|
|
programming example, 5-2
|
|||
|
|
LDD
|
|||
|
|
building with emake.exe, 3-14
|
|||
|
|
libraries
|
|||
|
|
customised, 3-10
|
|||
|
|
library
|
|||
|
|
building CLIB, 4-4
|
|||
|
|
CLIB missing DOS functions, 4-1
|
|||
|
|
CLIB notes on, 4-1
|
|||
|
|
machine
|
|||
|
|
detecting which SIBO system, 7-1
|
|||
|
|
manuals
|
|||
|
|
C SDK, 2-1
|
|||
|
|
Topspeed, 2-1
|
|||
|
|
multi-tasking
|
|||
|
|
applications - remarks on, 5-16
|
|||
|
|
multi-threaded
|
|||
|
|
applications - remarks on, 5-16
|
|||
|
|
programming, 5-2
|
|||
|
|
object oriented programming
|
|||
|
|
C++ and, 2-3
|
|||
|
|
Psion C approach, 2-3
|
|||
|
|
optimisation
|
|||
|
|
compilation warning, 3-11
|
|||
|
|
p_hello.c
|
|||
|
|
source code, 3-5
|
|||
|
|
p_iosignal
|
|||
|
|
function of, 5-14
|
|||
|
|
|
|||
|
|
|
|||
|
|
iii
|
|||
|
|
|
|||
|
|
|
|||
|
|
GENERAL PROGRAMMING MANUAL
|
|||
|
|
|
|||
|
|
|
|||
|
|
p_iowait
|
|||
|
|
remarks on, 5-4
|
|||
|
|
status words - declaring, 5-7
|
|||
|
|
status words - remarks on, 5-5
|
|||
|
|
p_ioyield
|
|||
|
|
remarks on, 5-14
|
|||
|
|
p_tickle
|
|||
|
|
function of, 5-13
|
|||
|
|
p_unmarka
|
|||
|
|
auto-switch-off, 5-14
|
|||
|
|
panic 80
|
|||
|
|
floating point emulator - CLIB, 4-3
|
|||
|
|
panics
|
|||
|
|
explained, 2-3
|
|||
|
|
number ranges, 2-3
|
|||
|
|
PC
|
|||
|
|
C programs, 1-1
|
|||
|
|
PC based
|
|||
|
|
development, 1-1
|
|||
|
|
PDD
|
|||
|
|
building with emake.exe, 3-14
|
|||
|
|
PLIB
|
|||
|
|
hello world application example, 3-4
|
|||
|
|
PLIB & CLIB
|
|||
|
|
contrasted, 3-4
|
|||
|
|
priorities
|
|||
|
|
processes - remarks on, 5-14
|
|||
|
|
priority
|
|||
|
|
application - control over, 3-12
|
|||
|
|
process priorities
|
|||
|
|
remarks on, 5-14
|
|||
|
|
program
|
|||
|
|
file transfer to SIBO system, 3-3
|
|||
|
|
program errors
|
|||
|
|
panics explained, 2-3
|
|||
|
|
program size
|
|||
|
|
application CLIB, 3-5
|
|||
|
|
application PLIB, 3-5
|
|||
|
|
programming
|
|||
|
|
asynchronous I/O, 5-2
|
|||
|
|
console device I/O in general, 5-6
|
|||
|
|
CPU yielding, 5-2
|
|||
|
|
documentation sources, 5-1
|
|||
|
|
error handling - a first look, 5-7
|
|||
|
|
error handling - in events, 5-7
|
|||
|
|
error handling - resource tidying, 5-8
|
|||
|
|
events - prioritisation of sources, 5-5
|
|||
|
|
events multiple source examples, 5-3
|
|||
|
|
example of background processing, 5-2
|
|||
|
|
example of keyboard input, 5-2
|
|||
|
|
example of serial port data input, 5-2
|
|||
|
|
example of sub-process completion, 5-2
|
|||
|
|
example of timer expiry, 5-2
|
|||
|
|
fundamental guide-lines, 5-1
|
|||
|
|
I/O devices in general, 5-5
|
|||
|
|
introduction - example source, 5-2
|
|||
|
|
introduction to, 5-1
|
|||
|
|
introduction to events - example apps, 5-2
|
|||
|
|
|
|||
|
|
|
|||
|
|
key presses - remarks on, 5-4
|
|||
|
|
multi-threaded, 5-2
|
|||
|
|
p_iowait - remarks on, 5-4
|
|||
|
|
p_iowait remarks on, 5-4
|
|||
|
|
p_iowait status words - declaring, 5-7
|
|||
|
|
p_iowait status words - remarks on, 5-5
|
|||
|
|
p_ioyield - remarks on, 5-14
|
|||
|
|
PC based development, 1-1
|
|||
|
|
semaphore I/O, 5-4
|
|||
|
|
timers cancelling in general, 5-6
|
|||
|
|
timers remarks on, 5-4
|
|||
|
|
user interface - simple examples, 5-2
|
|||
|
|
programs
|
|||
|
|
.img files, 3-1
|
|||
|
|
project file
|
|||
|
|
a first look at .pr files, 3-2
|
|||
|
|
advanced use, 3-11
|
|||
|
|
application project .pr files, 3-1
|
|||
|
|
epocinit statement, 3-6
|
|||
|
|
reusing - general, 3-6
|
|||
|
|
resource files
|
|||
|
|
application .rsc files, 3-13
|
|||
|
|
application .rzc compressed, 3-13
|
|||
|
|
screen sizes
|
|||
|
|
detecting which SIBO system, 7-1
|
|||
|
|
table of for SIBO systems, 7-1
|
|||
|
|
segment registers
|
|||
|
|
small code model, 4-2
|
|||
|
|
semaphore
|
|||
|
|
I/O remarks on, 5-4
|
|||
|
|
serial port
|
|||
|
|
comms debugging, 5-13
|
|||
|
|
data reception of, 5-11
|
|||
|
|
opening, 5-12
|
|||
|
|
serial port data input
|
|||
|
|
programming example, 5-2
|
|||
|
|
shell data files
|
|||
|
|
application, 3-13
|
|||
|
|
SIBO
|
|||
|
|
explained, 2-2
|
|||
|
|
systems family, 1-1
|
|||
|
|
SIBO SDK
|
|||
|
|
see C SDK, 2-1
|
|||
|
|
SIBO systems
|
|||
|
|
screen size table, 7-1
|
|||
|
|
software compatibility, 7-1
|
|||
|
|
what machine, 7-1
|
|||
|
|
small code model
|
|||
|
|
segment registers, 4-2
|
|||
|
|
small model code
|
|||
|
|
C SDK, 1-1
|
|||
|
|
software
|
|||
|
|
compatibility across SIBO systems, 7-1
|
|||
|
|
copy protection introduction, 6-1
|
|||
|
|
copy protection mechanism, 6-1
|
|||
|
|
stack size
|
|||
|
|
default, 3-6
|
|||
|
|
specifying, 3-6
|
|||
|
|
|
|||
|
|
|
|||
|
|
INDEX
|
|||
|
|
|
|||
|
|
|
|||
|
|
status words
|
|||
|
|
|
|||
|
|
declaring - p_iowait, 5-7
|
|||
|
|
stdepoc.h
|
|||
|
|
|
|||
|
|
include file, 3-11
|
|||
|
|
sub-process
|
|||
|
|
|
|||
|
|
contrasted with idle object, 5-16
|
|||
|
|
sub-process completion
|
|||
|
|
|
|||
|
|
programming example, 5-2
|
|||
|
|
SYS$NULL
|
|||
|
|
|
|||
|
|
chance to run auto-switch-off, 5-14
|
|||
|
|
timer expiry
|
|||
|
|
|
|||
|
|
programming example, 5-2
|
|||
|
|
timers
|
|||
|
|
|
|||
|
|
cancelling in general, 5-6
|
|||
|
|
|
|||
|
|
remarks on, 5-4
|
|||
|
|
Topspeed
|
|||
|
|
|
|||
|
|
Integrated Development Environment, 3-1
|
|||
|
|
Topspeed C
|
|||
|
|
|
|||
|
|
Clarion Software, 1-1
|
|||
|
|
|
|||
|
|
library reference, 2-1
|
|||
|
|
|
|||
|
|
package, 1-1
|
|||
|
|
ts.red file
|
|||
|
|
|
|||
|
|
C SDK redirection file, 1-3
|
|||
|
|
TSC vs TSCX
|
|||
|
|
|
|||
|
|
contrasted, 3-8
|
|||
|
|
tscfg
|
|||
|
|
|
|||
|
|
configuration file compiler, 3-11
|
|||
|
|
tsprj.txt
|
|||
|
|
|
|||
|
|
configuration file, 3-11
|
|||
|
|
user interface
|
|||
|
|
|
|||
|
|
programming examples, 5-2
|
|||
|
|
utility program
|
|||
|
|
|
|||
|
|
edump.exe, 3-12
|
|||
|
|
|
|||
|
|
emake.exe, 3-14
|
|||
|
|
|
|||
|
|
eremake.exe, 3-14
|
|||
|
|
version number
|
|||
|
|
|
|||
|
|
application - control over, 3-12
|
|||
|
|
versions
|
|||
|
|
|
|||
|
|
C SDK, 1-1
|
|||
|
|
what machine
|
|||
|
|
|
|||
|
|
detecting the SIBO system, 7-1
|
|||
|
|
window redraw
|
|||
|
|
|
|||
|
|
event source - remarks on, 5-16
|
|||
|
|
window server
|
|||
|
|
|
|||
|
|
WLIB library introduction, 3-5
|
|||
|
|
WLIB
|
|||
|
|
|
|||
|
|
introduction, 3-5
|
|||
|
|
yielding CPU
|
|||
|
|
|
|||
|
|
programming, 5-2
|
|||
|
|
|
|||
|
|
|