Purpose
This is the 68K assembly language version of our combination
application. It's one of the Palm
Samples.
Requirements
You need PilA (see tools section).
Source
code
Below is the .asm
file.
For .inc, .rcp,
.bmp, make-prc and
.prc, please download
the ZIP file.
; Combination.asm
; Palm
; Assembly language
; Special thanks to Darrin Massena, who provides great samples
; in assembly language for Palm
; His site is a MUST if you're interested in this language
; For more information see http://www.massena.com/darrin/pilot
; **************************************************************************
; APPLICATION section
; **************************************************************************
appl "Comb-Asm", 'CoAs' ;Application name and ID
include "Pilot.inc" ;System incs
include "Startup.inc"
include "combination.inc" ;Application incs
; **************************************************************************
; DATA section
; **************************************************************************
data ;(globals are a5-relative)
global gpfldN.l ;pointer to the n field
global gpfldP.l ;pointer to the p field
global gpfldFactorialN.l ;pointer to the n! field
global gpfldFactorialP.l ;pointer to the p! field
global gpfldFactorialNP.l ;pointer to the (n-p)! field
global gpfldCombination.l ;pointer to the combination(n,p) field
; **************************************************************************
; CODE section
; **************************************************************************
code
; ---------------------------------------------------------------------------
; DWord PilotMain(Word cmd, void *cmdPBP, Word launchflags)
; PilotMain is called by the startup code and implements a simple event handling loop.
; ---------------------------------------------------------------------------
proc PilotMain(cmd.w, cmdPBP.l, launchFlags.w)
local err.w
local evt.EventType
beginproc
tst.w cmd(a6) ;sysAppLaunchCmdNormalLaunch is 0
bne PmReturn ;not a normal launch, bag out
systrap FrmGotoForm(#MainForm.w)
PmEventLoop
; Doze until an event arrives
systrap EvtGetEvent(&evt(a6), #evtWaitForever.w)
; System gets first chance to handle the event
systrap SysHandleEvent(&evt(a6))
tst.b d0 ;handled?
bne.s PmEventDone ;yep
; Menu handler gets second chance to handle the event
systrap MenuHandleEvent(&0, &evt(a6), &err(a6))
tst.b d0 ;handled?
bne.s PmEventDone ;yep
; Application handler gets third chance to handle the event
call ApplicationHandleEvent(&evt(a6))
tst.b d0 ;handled?
bne.s PmEventDone ;yep
; Form handler gets fourth chance to handle the event
call MainFormHandleEvent(&evt(a6))
tst.b d0 ;handled?
bne.s PmEventDone ;yep
; Still not handled. We're not interested in it anymore so let the
; default form handler take it.
systrap FrmGetActiveForm()
systrap FrmHandleEvent(a0.l, &evt(a6))
; Return from PilotMain when an appStopEvent is received
PmEventDone
cmpi.w #appStopEvent,evt+EventType.eType(a6) ;time to stop?
bne.s PmEventLoop ;nope, loop until it is
systrap FrmCloseAllForms() ;to avoid memory leaks
PmReturn
moveq #0,d0
endproc
; ---------------------------------------------------------------------------
; Boolean ApplicationHandleEvent(EventType *pevt)
; ---------------------------------------------------------------------------
proc ApplicationHandleEvent(pevt.l)
beginproc
movem.l a3,-(a7) ;save registers we're going to trash
movea.l pevt(a6),a0 ;a0 = pevt
; Handle frmLoadEvent
cmpi.w #frmLoadEvent,EventType.eType(a0) ;frmLoadEvent?
bne AHENotHandled ;no
; Initialize the form and make it active
systrap FrmInitForm(EventType.data+frmLoad.formID(a0).w)
move.l a0,a3 ;save a copy of FormPtr for later
systrap FrmSetActiveForm(a0.l)
; Get pointers to the form fields and store'em into globals
systrap FrmGetObjectIndex(a3.l, #MainN.w)
systrap FrmGetObjectPtr(a3.l,d0.w)
move.l a0,gpfldN(a5)
systrap FrmGetObjectIndex(a3.l, #MainP.w)
systrap FrmGetObjectPtr(a3.l,d0.w)
move.l a0,gpfldP(a5)
systrap FrmGetObjectIndex(a3.l, #MainFactorialN.w)
systrap FrmGetObjectPtr(a3.l,d0.w)
move.l a0,gpfldFactorialN(a5)
systrap FrmGetObjectIndex(a3.l, #MainFactorialP.w)
systrap FrmGetObjectPtr(a3.l,d0.w)
move.l a0,gpfldFactorialP(a5)
systrap FrmGetObjectIndex(a3.l, #MainFactorialNP.w)
systrap FrmGetObjectPtr(a3.l,d0.w)
move.l a0,gpfldFactorialNP(a5)
systrap FrmGetObjectIndex(a3.l, #MainCombination.w)
systrap FrmGetObjectPtr(a3.l,d0.w)
move.l a0,gpfldCombination(a5)
moveq.l #1,d0 ;event handled
bra.s AHEReturn
AHENotHandled
clr.b d0
AHEReturn
movem.l (a7)+,a3
endproc
; ---------------------------------------------------------------------------
; Boolean MainFormHandleEvent(EventType *pevt)
; ---------------------------------------------------------------------------
proc MainFormHandleEvent(pevt.l)
beginproc
movea.l pevt(a6),a0 ;a0 = pevt
move.w EventType.eType(a0),d0
; Handle frmOpenEvent
cmp.w #frmOpenEvent,d0
bne MFH1
; Draw the form
systrap FrmGetActiveForm()
systrap FrmDrawForm(a0.l)
moveq.l #1,d0
bra MFHReturn
; Handle frmMenuEvent
MFH1
cmp.w #menuEvent,d0
bne MFH2
cmp.w #MainOptionsHelpCmd,EventType.data+menu.itemID(a0)
bne MFHTestAbout
; Handle HelpCmd
systrap FrmAlert(#HelpAlert.w)
bra MFHMenuDone
MFHTestAbout
cmp.w #MainOptionsAboutCmd,EventType.data+menu.itemID(a0)
bne MFHNotHandled
; Handle HelpCmd
systrap FrmAlert(#AboutAlert.w)
MFHMenuDone
moveq.l #1,d0
bra MFHReturn
; Handle ctlSelectEvent
MFH2
cmp.w #ctlSelectEvent,d0
bne MFHNotHandled
; Compute button clicked?
cmp.w #MainCompute,EventType.data+ctlEnter.controlID(a0)
bne MFHNotHandled
jsr Go(pc) ;yes, call our main function
bra MFHReturn
MFHNotHandled
clr.b d0
MFHReturn
endproc
; ---------------------------------------------------------------------------
; DWord Factorial(Word n)
; ---------------------------------------------------------------------------
proc Factorial(n.w)
beginproc
movem.l d1,-(a7) ;save registers that we'll overwrite locally
move.w n(a6),d1 ;we'll use d1 to decrement
move.w #1,d0
cmp.w #1,d1 ;if n <= 1, we've already got the result in d0!
blt FCTReturn
FCTLoop
mulu d1,d0 ;multiply
subi #1,d1 ;decrement
bne FCTLoop ;check > 0
FCTReturn
movem.l (a7)+,d1 ;restore registers
endproc
; ---------------------------------------------------------------------------
; DWord Combination(Word n, Word p)
; ---------------------------------------------------------------------------
proc Combination(n.w,p.w)
beginproc
movem.l d1-d3,-(a7) ;save registers that we'll overwrite locally
call Factorial(n.w(a6))
move.w d0,d1 ;d1 = n!
call Factorial(p.w(a6))
move.w d0,d2 ;d2 = p!
move n.w(a6),d0
sub.w p.w(a6),d0
call Factorial(d0.w)
move.w d0,d3 ;d3 = (n-p)!
move.w d2,d0 ;d0 = p!
mulu d3,d0 ;d0 = (n-p)! * p!
divu d0,d1 ;d1 = result
move.w d1,d0 ;return result in d0
movem.l (a7)+,d1-d3 ;restore registers
endproc
; ---------------------------------------------------------------------------
; void Go(void)
; ---------------------------------------------------------------------------
proc Go()
local n.w
local p.w
beginproc
call GetField(gpfldN.l(a5))
move.w d0,n(a6) ;save N
call GetField(gpfldP.l(a5))
move.w d0,p(a6) ;save P
call Factorial(n.w(a6)) ;compute n!
call SetField(d0.l,gpfldFactorialN.l(a5)) ;display result
call Factorial(p.w(a6)) ;compute p!
call SetField(d0.l,gpfldFactorialP.l(a5)) ;display result
move.w n(a6),d0
sub.w p(a6),d0
call Factorial(d0.w) ;compute (n-p)!
call SetField(d0.l,gpfldFactorialNP.l(a5)) ;display result
call Combination(n.w(a6),p.w(a6)) ;compute combination(n,p)
call SetField(d0.l,gpfldCombination.l(a5)) ;display result
systrap FrmGetActiveForm()
systrap FrmDrawForm(a0.l) ;Redraw form
endproc
; ---------------------------------------------------------------------------
; void GetField(Word field)
; ---------------------------------------------------------------------------
proc GetField(field.l)
beginproc
move.l field.l(a6),a0 ;load adr of our field
systrap FldGetTextPtr(a0.l) ;get ptr to field
systrap StrAToI(a0.l) ;convert field to number
endproc
; ---------------------------------------------------------------------------
; void SetField(Word value, Word field)
; ---------------------------------------------------------------------------
proc SetField(value.l,field.l)
local szBuffer.8
beginproc
movem.l a3,-(a7) ;save registers that we'll overwrite locally
move.l value.l(a6),-(a7) ;push integer
pea.l szBuffer(a6) ;push pointer to string buffer
trap #15
dc.w sysTrapStrIToA
addq.l #8,a7 ;pop the args off the stack
move.l field.l(a6),a3
systrap FldFreeMemory(a3.l) ;free field memory
systrap StrLen(&szBuffer(a6)) ;calculate buffer length
lea.l szBuffer(a6),a0 ;load buffer address
systrap FldInsert(a3.l,a0.l,d0.w) ;insert buffer into field
movem.l (a7)+,a3 ;restore registers
endproc
; **************************************************************************
; RESOURCE section
; **************************************************************************
; Version resource
res 'tver', AppVersion, "tver0001.bin"
; Icon and SmallIcon resources
res 'tAIB', AppIcon, "taib03e8.bin"
res 'tAIB', AppSmallIcon, "taib03e9.bin"
; 'pref' resource. Defines app launch flags, stack and heap size
res 'pref', AppPref
dc.w sysAppLaunchFlagNewStack|sysAppLaunchFlagNewGlobals|sysAppLaunchFlagUIApp|sysAppLaunchFlagSubCall
dc.l $1000 ; stack size
dc.l $1000 ; heap size
; Form resources
res 'tFRM', MainForm, "tfrm03e8.bin"
; Menu resources
res 'MBAR', MainMenu, "mbar03e8.bin"
; Alert resources
res 'Talt', HelpAlert, "talt03e8.bin"
res 'Talt', AboutAlert, "talt03e9.bin"
Comments
See how big the source code is? Rite, there's a lot
of overhead! But actually, the executable is pretty small. It weighs
2424 bytes versus 3101 bytes for the C version of the very same
app, which means... 25% smaller, not to mention that this 68K version
is quicker than any of our samples in the combination
category!
If you take a closer look at the source code, you'll
see that Palm API's are directly invokable thru wrappers, as system
traps. Like:
systrap FrmDrawForm(a0.l) ;Redraw form
Also, PilA provides you with an easy way of making
your application modular. You may define a function that takes arguments,
like this: proc Combination(n.w,p.w)
and invoke it like that: call Combination(n.w(a6),p.w(a6)).
Again, the core functions are : Factorial,
Combination and Go.
Next sample
|