# Diamond Divide Macro (40) Mod

Posted by k-Pack, 14 June 2018 · 169 views

Diamond macro

While programing dMetronome I had to learn a few things. How to divide the number of DLIs in a minute by the number of DLIs to get beats per min.  I finally got to the point where I could use the Diamond Macro Divide to handle the division and as long as I kept the answer to one byte I was fine but there were many tribulations along the way.

My first revelation was that the macro needed the numbers to be passed to them.  Many of the d-macros pass the address pointer to W0 to W7 but not the divide and multiply macros.  They require that the numbers be passed to the macro.  The answer is much different when dividing two numbers or two address .

The macros were changed to accept 2 addresses as pointers and then the macro moves the numbers at those addresses into W4 and W5.  The answer of the division will be located at W6 and W7.

Original DIVIDE Macro
8630 ;
8640     .MACRO DIVIDE
8650     LDA # <%1   ;NUMBER
8660     STA W4
8670     LDA # >%1
8680     STA W4+1
8690     LDA # <%2   ;DIVISOR
8700     STA W5
8710     LDA # >%2
8720     STA W5+1
8730     LDA #DIVIDE
8740     JSR DIAMOND
8750     .ENDM
8760 ;

Modified Macro
8630 ;
8636 ;KPACK - 5/16/2018
8640     .MACRO DIVIDE
8650     LDA %1      ;NUMBER
8660     STA W4
8670     LDA %1+1
8680     STA W4+1
8690     LDA %2      ;DIVISOR
8700     STA W5
8710     LDA %2+1
8720     STA W5+1
8730     LDA #DIVIDE
8740     JSR DIAMOND
8750     .ENDM
8760 ;

This would seem to make more sense but luckily on the first try I used 2 numbers that yielded erroneous results.  The following program was used to test the modified macro.  Change the values for NUM01 and NUM02, compile to evaluate the result.

Test Program
10 ;THIS PROGRAM IS TO TEST CHANGES
20 ;MADE TO THE DIAMOND MACRO LIBRARY
30 ;
50 ;NOT NUMBERS
60 ; DOUBLE BYTE MATH ON TWO NUMBERS.
70 ; RESULTS PRINTED IN HEX.
80 ;
90 ;
0100     .OPT NO LIST
0110     .OPT OBJ
0120     *=  \$2200
0130     .INCLUDE #D2:DMACRO01.M65
0140 ;
0150 NUM01 .WORD 1211
0160 NUM02 .WORD 37
0180 DIVRST .WORD 0  ; DIV RESULTS
0190 DIVREM .WORD 0  ; DIV REMAINDER
0200 DVAR .WORD 0  ;Used to hold print variable
0210 HEXSTG .BYTE "\$    ",255 ; 4 spaces for double byte
0220 HEXCHR .BYTE \$30,\$31,\$32,\$33,\$34
0230     .BYTE \$35,\$36,\$37,\$38,\$39
0240     .BYTE \$41,\$42,\$43,\$44,\$45
0250     .BYTE \$46
0260 ;
0270 START  INIT  0
0280      DIVIDE  NUM01,NUM02
0290     LDA W6      ;STORE RESULTS
0300     STA DIVRST
0310     LDA W6+1
0320     STA DIVRST+1
0330     LDA W7
0340     STA DIVREM
0350     LDA W7+1
0360     STA DIVREM+1
0370     LDA NUM01   ;LOAD NUM TO CONVERT
0380     STA DVAR
0390     LDA NUM01+1
0400     STA DVAR+1
0410     JSR DB2HEX
0420      SYSDRAW  HEXSTG,10,20,0
0430     LDA NUM02   ;LOAD NUM TO CONVERT
0440     STA DVAR
0450     LDA NUM02+1
0460     STA DVAR+1
0470     JSR DB2HEX
0480      SYSDRAW  HEXSTG,10,30,0
0490     LDA DIVRST  ;LOAD NUM TO CONVERT
0500     STA DVAR
0510     LDA DIVRST+1
0520     STA DVAR+1
0530     JSR DB2HEX
0540      SYSDRAW  HEXSTG,10,50,0
0550     LDA DIVREM  ;LOAD NUM TO CONVERT
0560     STA DVAR
0570     LDA DIVREM+1
0580     STA DVAR+1
0590     JSR DB2HEX
0600      SYSDRAW  HEXSTG,10,60,0
0610 LOOP  EVENT
0620     LDA EVENTTYPE
0630     BEQ LOOP
0640      EXIT       ;DIAMOND
0650      EXECDESKTOP
0660 ;
0670 ;
0680 ;CONVERT HEX TO STRING
0690 DB2HEX LDA DVAR
0700     AND #\$0F
0710     TAX
0720     LDA HEXCHR,X
0730     STA HEXSTG+4
0740     LSR DVAR
0750     LSR DVAR
0760     LSR DVAR
0770     LSR DVAR
0780     LDX DVAR
0790     LDA HEXCHR,X
0800     STA HEXSTG+3
0810     LDA DVAR+1
0820     AND #\$0F
0830     TAX
0840     LDA HEXCHR,X
0850     STA HEXSTG+2
0860     LSR DVAR+1
0870     LSR DVAR+1
0880     LSR DVAR+1
0890     LSR DVAR+1
0900     LDX DVAR+1
0910     LDA HEXCHR,X
0920     STA HEXSTG+1
0930     RTS
0940 ;
0950     *=  \$02E0
0960     .WORD START

This is a list of the numbers used for the tests and the results as printed to the screen.

Test  NUM01 / NUM02 = Result   Remainder
(W4)       (W5)         (W6)        (W7)
1        \$04BB      \$0025      \$0020       \$001B
2        \$FFFF      \$0001       crash
3        \$FFFF      \$FFFF      crash
4        \$B478      \$C3B2      crash
5        \$0000      \$F2F7       \$0000      \$0000
6        \$F2F7      \$0AB4      crash
-
7        \$FFFE      \$0002      crash
8        \$0FFF      \$0002      \$07FF       \$0001
-
9         \$7FFF      \$0002      \$3FFF       \$0001
10       \$8000      \$0002       crash
-
11       \$0002     \$7FFF      \$0000       \$0002
12       \$0002     \$8000     \$0000       \$0002
13       \$0002     \$FFFF      \$0000       \$0002
14       \$7FFF      \$7FFF      \$0001      \$0000
15       \$75D1     \$72A5     \$0001      \$032C

After test 6 it was noted that any number that had bit 15 set might crash Diamond 3.0. Test 7 and 8 proved that it is within the upper 4 bits of the double byte number that a problem occurred.  Test 9 and 10 proved that it was bit 15 that was the problem.  Tests 11 - 15 were tried to verify the crash point.

In conclusion I believe (at this moment in time) that the DIVIDE macro, as modified, will accept the addr-s for 2 numbers and give the proper results if:

• The numerator (NUM01) is between 0 - 32767 (\$0000 - \$7FFF).
• The denominator(NUM02) is a double byte number but not 0.

Disclaimer:
I have only tested the Divide Diamond function on my Diamond 3.0 cartridge.  I have included the ATR with  the source files so you can generate test results on your system. You'll need the MAC/65 cart.

div macro test.zip (19.44KB)

I'm not up to delving into the Diamond Source code and will simply try to stay within the restrictions defined above. Of course, if these assumptions are incorrect I won't find out until after I click "Publish".

When the tests on the multiply function have been finalized a report will be issued.

S M T W T F S
12345
6789101112
131415 16 171819
20212223242526
2728293031