UM* (multiplication) bug in common 6502 Forths

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
User avatar
MichaelM
Posts: 761
Joined: 23 Apr 2012
Location: Huntsville, AL

Re: UM* (multiplication) bug in common 6502 Forths

Post by MichaelM »

Garth/Ed:

Thanks very much for the replies. I can assume then that an unsigned mixed precision instruction/subroutine/primitive might be helpful to implement.

I typically work with fixed point signal processing algorithms. As such, I hardly ever use the lower half of a signed/unsigned multiplication product. The results that I'm after are almost always contained in the upper half of the product.

Since I tend to build these functions in custom hardware, I tend to forget about the fact that all HLL languages have no support for multiplication in the sense that I require. Even on the MIPS architecture, most languages return the lower half of the product even though a dedicated register is provided that holds the upper half of the product.

Perhaps I've never properly used casting to get the proper product. Invariably to make the code work properly in an HLL, I've always had to cast the multiplier and multiplicand into next larger integer size. This tends to generate a bigger product which is not directly supported which generates library calls, etc. etc.

(-0.5)*(-0.5) = 0.25 <=> (-128/256)*(-128/256) = (16384/65536)
Michael A.
User avatar
MichaelM
Posts: 761
Joined: 23 Apr 2012
Location: Huntsville, AL

Re: UM* (multiplication) bug in common 6502 Forths

Post by MichaelM »

Ed:

Thanks for the pointer to that article; pulled it down for later reading.

Somewhere in my stash of stuff I have some 6809 databooks and other what nots from th 80's. I may look for them this week. There may be some ideas to glean in the referenced article for a new project.
Michael A.
edx
Posts: 14
Joined: 14 Sep 2014

Re: UM* (multiplication) bug in common 6502 Forths

Post by edx »

I knew of a U/ bug in 6502 fig-forth (it was well publicized) but never heard of issues with U*. This prompted some digging. There's a discrepancy in the U* code published in the Fig Installation Manual (Nov 1980) and what's contained in Fig 6502 Rel 1.1 asm listing (Sep 1980) from http://www.forth.org/fig-forth/contents.html

Below is a chart comparing the code for U* U/ found in several '6502 fig-forth'.

Code: Select all

; U* U/ code comparison for 6502 Fig-Forth

; FIG INST MANUAL           6502 Rel 1.1 ASM      HES 64FORTH           AIM-65 FORTH

CODE U*
     SEC      LDA,           LDA     2,X           LDA     2,X           LDA     2,X
     N        STA,           STA     N             STA     N             STA     N
     SEC      STY,           STY     2,X           STY     2,X           STY     2,X
     SEC 1+   LDA,           LDA     3,X           LDA     3,X           LDA     3,X
     N 1+     STA,           STA     N+1           STA     N+1           STA     N+1
     SEC 1+   STY,           STY     3,X           STY     3,X           STY     3,X
     16 #     LDY,           LDY     #16           LDY     #16           LDY     #16
 BEGIN,                L396                  L84DC                 LB464
     BOT 2+   ASL,           ASL     2,X           ASL     2,X           ASL     2,X
     BOT 3 +  ROL,           ROL     3,X           ROL     3,X           ROL     3,X
     BOT      ROL,           ROL     0,X           ROL     0,X           ROL     0,X
     BOT 1+   ROL,           ROL     1,X           ROL     1,X           ROL     1,X
 CS IF,                      BCC     L411          BCC     L84FB         BCC     LB483
              CLC,           CLC                   CLC                   CLC
     N        LDA,           LDA     N             LDA     N             LDA     N
     BOT 2 +  ADC,           ADC     2,X           ADC     2,X           ADC     2,X
     BOT 2 +  STA,           STA     2,X           STA     2,X           STA     2,X
     N 1+     LDA,           LDA     N+1           LDA     N+1           LDA     N+1
     BOT 3 +  ADC,           ADC     3,X           ADC     3,X           ADC     3,X
     BOT 3 +  STA,           STA     3,X           STA     3,X           STA     3,X

 CS IF,                                            BCC     L84FB         BCC     LB483
     BOT      INC,           LDA     #0            INC     0,X           INC     0,X
 0= IF,                      ADC     0,X           BNE     L84FB         BNE     LB483
     BOT 1+   INC,           STA     0,X           INC     1,X           INC     1,X

 ENDIF, ENDIF, ENDIF,  L411                  L84FB                 LB483
              DEY,           DEY                   DEY                   DEY
 0= UNTIL,                   BNE     L396          BNE     L84DC         BNE     LB464
     NEXT     JMP,           JMP     NEXT          JMP     NEXT          JMP     NEXT


; FIG INST MANUAL           6502 Rel 1.1 ASM      HES 64FORTH           AIM-65 FORTH

CODE  U/
                                                   STY     N+1
      SEC 2 + LDA,           LDA     4,X           LDA     4,X           LDA     4,X
      SEC     LDY,           LDY     2,X           LDY     2,X           LDY     2,X
      SEC 2 + STY,           STY     4,X           STY     4,X           STY     4,X
      .A      ASL,           ASL     A             ASL     A             ASL     A
      SEC     STA,           STA     2,X           STA     2,X           STA     2,X
      SEC 3 + LDA,           LDA     5,X           LDA     5,X           LDA     5,X
      SEC 1+  LDY,           LDY     3,X           LDY     3,X           LDY     3,X
      SEC 3 + STY,           STY     5,X           STY     5,X           STY     5,X
      .A      ROL,           ROL     A             ROL     A             ROL     A
      SEC 1+  STA,           STA     3,X           STA     3,X           STA     3,X
      16 #    LDA,           LDA     #16           LDA     #16           LDA     #16
      N       STA,           STA     N             STA     N             STA     N
 BEGIN,                L433                  L8520                 LB4A6
      SEC 2 + ROL,           ROL     4,X           ROL     4,X           ROL     4,X
      SEC 3 + ROL,           ROL     5,X           ROL     5,X           ROL     5,X
                                                   ROL     N+1           PHP
              SEC,           SEC                   SEC                   SEC
      SEC 2 + LDA,           LDA     4,X           LDA     4,X           LDA     4,X
      BOT     SBC,           SBC     0,X           SBC     0,X           SBC     0,X
              TAY,           TAY                   TAY                   TAY
      SEC 3 + LDA,           LDA     5,X           LDA     5,X           LDA     5,X
      BOT 1+  SBC,           SBC     1,X           SBC     1,X           SBC     1,X

                                                   PHA                   BCC     LB4BF
                                                   LDA     N+1           STY     4,X
                                                   SBC     #0            STA     5,X
                                                   LDA     #0            PLP
                                                   STA     N+1           SEC
                                                   PLA                   BCS     LB4C6
                                                                   LB4BF PLP

 CS IF,                      BCC     L444          BCC     L8540         BCC     LB4C6
      SEC 2+  STY,           STY     4,X           STY     4,X           STY     4,X
      SEC 3 + STA,           STA     5,X           STA     5,X           STA     5,X
 THEN,                 L444                  L8540                 LB4C6
      SEC     ROL,           ROL     2,X           ROL     2,X           ROL     2,X
      SEC 1+  ROL,           ROL     3,X           ROL     3,X           ROL     3,X
      N       DEC,           DEC     N             DEC     N             DEC     N
 0= END,                     BNE     L433          BNE     L8520         BNE     LB4A6
      POP     JMP,           JMP     POP           JMP     POP           JMP     POP

JimBoyd
Posts: 931
Joined: 05 May 2017

Re: UM* (multiplication) bug in common 6502 Forths

Post by JimBoyd »

edx wrote:
I knew of a U/ bug in 6502 fig-forth (it was well publicized) but never heard of issues with U*.
The problem with U* was known in 1983. In the March/April 1983 issue of Forth Dimensions ( Vol. 4 no. 6 ), on page 25 under Technotes, a reader points out another bug in FIG Forth. In his reply, Bill Ragsdale mentions the carry problems in U* and U/.
Bill Ragsdale wrote:
Most vendors who follow the FIG Model have corrected this and several other problems (carry problems in U* and U/, expanding buffer size to 1024 bytes and Y register range in ENCLOSE). These updates point out the advantage of software products with vendor support, additional testing and review. The self installed FIG system has had remarkable acceptance, but it cannot supplant the broader resources of commercial offerings.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: UM* (multiplication) bug in common 6502 Forths

Post by GARTHWILSON »

Forum member TobyLobster has done extensive work comparing over 60 6502 integer multiply methods, and done a great compilation at https://github.com/TobyLobster/multiply_test .  The original post is at viewtopic.php?f=2&t=7451 .
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Post Reply