Date : Tue, 25 Sep 2001 18:52:35 +0100
From : "Fewell, Steve" <Steve.Fewell@...>
Subject: BASIC 4 - Integer Multiplication routine disassembly
As the Acorn ROMs are now freeware (?), I decided to begin something I've
been wanting to do for a long time, that is to produce listings of BASIC 4
ROM's routines, together with detailed descriptions of how they work.
I decided to choose the Integer Multiplication routine as my first example.
Please let me know what you think, and whether you'd like to see more like
it. If anyone else wants to have a go at writing up with me then please feel
free to post your own descriptions of routines from BASIC 4 (or another
version of BASIC).
If anyone wants to host such descriptions on their website, then I'd be
happy for them to. Please let me know if you can, so that I can send them to
you, instead of the list, so that people can look for updates on your
website, instead of lengthy postings appearing on the mailing list. Also, if
anyone can host this, and wants to HTMLise it, then please do so. I can
follow the HTML format for future routines, of course this would have to be
on a website, and not sent to the mailing list.
If I've made a mistake, and someone wants to correct/expand on something,
then please do so.
Ok, here is the routine description:
Routine: imult
Name: Integer Multiplication
Starting Address: &9F64
Entry criteria: IWA [1] contains the first Integer number. Y contains the
Most Significant Byte of this Integer number (?&2D). ?&4 and ?&5 point to
the second Integer variable. ?&27 = 4, X = &4.
Notes: If the IWA > &FFFF, it is truncated to 16 bits.
Exit: IWA contains the result of [Integer variable * IWA]
Description:
Exclusive-OR the Most significant bytes of both integers together, this
determines the sign of the result (if only one of the MSBs is negative then
the result is negative, otherwise it is positive).
Make both integers positive [using &ACBE] (so that we only have to do
positive multiplication).
Store the multiplier in zero-page locations (&39 to &3C) and put the
multiplicand into the IWA [popi].
Initialise the result to zero (The result is stored in Y [&3D], X [&3E], &3F
and &40).
Keep repeating the following loop until the multiplier is zero [only the
least significant two bytes of the multiplier are used]:
(1) Divide the multiplier by 2 (and make the result integer)
(2) If an integer result was not obtained, (i.e. Multiplier was an odd
number before division) then add the multiplicand to the result. [Dividing
the multiplier lost 0.5 of its value, so we add on the multiplicand (which
at this stage is worth 0.5 * the actual multiplicand) before it is
multiplied to perform the multiplication of the lost 0.5 of the multiplier].
(3) Multiply the multiplicand by 2
Until multiplier is zero ((&39 OR &3A) = zero).
Retrieve the result from the zero page locations (&3D to &40) and make it
negative if the sign [at the beginning] was determined to be negative.
Jump to &9FCA to test the value of X [the next operator] when the routine
was entered. If X contains the operator code for '*', '/', 'MOD' or 'DIV'
then send the result to the appropriate routine, for further calculation,
otherwise exit the multiplication routine.
[1] The IWA is the Integer working area A, this is a 4-byte zero-page
location for the temporary storage of one 32-bit Integer number. It's
location is &2A (least significant byte) to &2D (most significant byte).
Following is the disassembly for the integer multiplication routine (it
should be read in a fixed-proportioned font, like Courier New)
9F64 Z 090 5A PHY
9F65 032 190 172 20 BE AC JSR &ACBE ipos
9F68 ' 134 039 86 27 STX &27
9F6A 9 162 057 A2 39 LDX#&39
9F6C 032 198 189 20 C6 BD JSR &BDC6 izpout
9F6F 032 230 188 20 E6 BC JSR &BCE6 popi
9F72 h 104 68 PLA
9F73 E- 069 045 45 2D EOR &2D
9F75 7 133 055 85 37 STA &37
9F77 032 190 172 20 BE AC JSR &ACBE ipos
9F7A 160 000 A0 00 LDY#&00
9F7C 162 000 A2 00 LDX#&00
9F7E d? 100 063 64 3F STZ &3F
9F80 d@ 100 064 64 40 STZ &40
9F82 F: 070 058 46 3A LSR &3A
9F84 f9 102 057 66 39 ROR &39
9F86 144 021 90 15 BCC 21 --> &9F9D
9F88 024 18 CLC
9F89 152 98 TYA
9F8A e* 101 042 65 2A ADC &2A
9F8C 168 A8 TAY
9F8D 138 8A TXA
9F8E e+ 101 043 65 2B ADC &2B
9F90 170 AA TAX
9F91 ? 165 063 A5 3F LDA &3F
9F93 e, 101 044 65 2C ADC &2C
9F95 ? 133 063 85 3F STA &3F
9F97 @ 165 064 A5 40 LDA &40
9F99 e- 101 045 65 2D ADC &2D
9F9B @ 133 064 85 40 STA &40
9F9D * 006 042 06 2A ASL &2A
9F9F &+ 038 043 26 2B ROL &2B
9FA1 &, 038 044 26 2C ROL &2C
9FA3 &- 038 045 26 2D ROL &2D
9FA5 9 165 057 A5 39 LDA &39
9FA7 : 005 058 05 3A ORA &3A
9FA9 208 215 D0 D7 BNE -41 --> &9F82
9FAB = 132 061 84 3D STY &3D
9FAD > 134 062 86 3E STX &3E
9FAF 7 165 055 A5 37 LDA &37
9FB1 008 08 PHP
9FB2 = 162 061 A2 3D LDX#&3D
9FB4 032 128 170 20 80 AA JSR &AA80 izpin
9FB7 ( 040 28 PLP
9FB8 016 003 10 03 BPL 3 --> &9FBD
9FBA 032 222 172 20 DE AC JSR &ACDE icomp
9FBD ' 166 039 A6 27 LDX &27
9FBF 128 009 80 09 BRA 9 --> &9FCA
9FC1 L; 076 059 159 4C 3B 9F JMP &9F3B
9FC4 & 032 038 188 20 26 BC JSR &BC26 pushi
9FC7 032 018 160 20 12 A0 JSR &A012
9FCA * 224 042 E0 2A CPX#&2A
9FCC 240 243 F0 F3 BEQ -13 --> &9FC1
9FCE / 224 047 E0 2F CPX#&2F
9FD0 240 009 F0 09 BEQ 9 --> &9FDB
9FD2 224 131 E0 83 CPX#&83
9FD4 240 031 F0 1F BEQ 31 --> &9FF5
9FD6 224 129 E0 81 CPX#&81
9FD8 # 240 035 F0 23 BEQ 35 --> &9FFD
9FDA ` 096 60 RTS