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 ;
8635 ;MODIFIED TO LOAD NUM FROM ADDR.
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 ;
40 ;MACRO NOW LOADS NUMBERS AT ADDR.
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.
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.
0 Comments
Recommended Comments
There are no comments to display.