Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Mul-table challenge
2005-10-17 13:26
Graham
Account closed

Registered: Dec 2002
Posts: 990
Mul-table challenge

I was just coding another multiplication and once again I had to code a mul-table generator. Somehow I felt like doing it as small as possible and settle this forever. The routine should create:

- function: int((x*x)/4)
- x = 0 to 511
- two tables: 512 low bytes and 512 high bytes
- no dependencies on previous zeropage or register settings

So far I managed to do it in 54 bytes (RTS not included), is anyone able to do a smaller version?

EDIT:

53 bytes now :)
2005-10-17 14:16
Monte Carlos

Registered: Jun 2004
Posts: 359
; (x+1)^2=x^2+(2x+1)
; Always add the next odd number to the prev. square.

lda #<table
sta zptr
lda #>table
sta zptr+1 ;= 8byt

lda #0
sta add
sta add+1
tax
tay ;=8 byt

loop:
clc
adc add
sta (zptr),y
pha
iny
txa
adc add+1
sta (zptr),y
tax
pla
inc add
inc add
bne *+4
inc add+1

iny
bne loop ;= 25 byt
inc zptr+1
ldy zptr+1
cpy #>ende
ldy #0
bcc loop
rts;11 byt

; 8+8+25+11 = ges 52

;Greetings Monte Carlos
2005-10-17 14:16
Monte Carlos

Registered: Jun 2004
Posts: 359
Shit, i forgot the division by 4!!!!
Sorry!
2005-10-17 14:17
Monte Carlos

Registered: Jun 2004
Posts: 359
; (x+1)^2=x^2+(2x+1)
; Always add the next odd number to the prev. square.

lda #<table
sta zptr
lda #>table
sta zptr+1 ;= 8byt

lda #0
sta add
sta add+1
tax
tay ;=8 byt

loop:
clc
adc add
sta (zptr),y
pha
iny
txa
adc add+1
sta (zptr),y
tax
pla
inc add
inc add
bne *+4
inc add+1

iny
bne loop ;= 25 byt
inc zptr+1
ldy zptr+1
cpy #>ende
ldy #0
bcc loop
rts;11 byt

; 8+8+25+11 = ges 52

;Greetings Monte Carlos
2005-10-17 14:20
Monte Carlos

Registered: Jun 2004
Posts: 359
Shit, the post appeared two times!
It was the "back" button of Mozilla, which
caused submitting of an already submitted entry!
Stupid ;)
2005-10-17 14:27
WVL

Registered: Mar 2002
Posts: 902
those are 256 byte tables :)
2005-10-17 14:38
Cruzer

Registered: Dec 2001
Posts: 1048
Graham, just post your code already. 53 bytes sounds good enough for me :)
2005-10-17 14:44
Graham
Account closed

Registered: Dec 2002
Posts: 990
I'll post the code later on. Don't want to destroy new ideas by infecting other peoples brains with my approach :)
2005-10-17 14:51
Oswald

Registered: Apr 2002
Posts: 5094
I have always created those tables in basic..
2005-10-17 15:27
Graham
Account closed

Registered: Dec 2002
Posts: 990
And wasted (1024-x) bytes...
2005-10-17 15:53
tlr

Registered: Sep 2003
Posts: 1790
You didn't say it had to be reentrant or runnable in ROM so I assume selfmod is fine.
My routine is 42 bytes excluding the rts. :)
2005-10-17 16:00
Oswald

Registered: Apr 2002
Posts: 5094
Graham: yeah, so my vector parts load 0.1 second slower, did you notice ? :(
2005-10-17 16:05
Graham
Account closed

Registered: Dec 2002
Posts: 990
Assuming that that table was the only one.
2005-10-17 16:08
Ben
Account closed

Registered: Feb 2003
Posts: 163
Graham, please hold yourself from posting the answer a couple of days so I can give it a thought..
2005-10-17 16:12
tlr

Registered: Sep 2003
Posts: 1790
Quote: You didn't say it had to be reentrant or runnable in ROM so I assume selfmod is fine.
My routine is 42 bytes excluding the rts. :)


Ok, shaved another byte off. 41 bytes excluding rts.
2005-10-17 16:20
Graham
Account closed

Registered: Dec 2002
Posts: 990
42 bytes with 512 entries and not 256?
2005-10-17 16:23
tlr

Registered: Sep 2003
Posts: 1790
Quote: 42 bytes with 512 entries and not 256?

Yes 512 entries. Shaved another 2 bytes. 39 bytes excluding rts. :)
2005-10-17 16:29
Graham
Account closed

Registered: Dec 2002
Posts: 990
Ok this is getting interesting :) Did you verify the resulting table against some basic generator?

10 FOR I=0 TO 511
20 X = INT((X*X)/4)
30 XH = INT(X/256)
40 XL = X - (XH*256)
50 POKE 8192+I,XL
60 POKE 8704+I,XH
70 NEXT
2005-10-17 16:31
tlr

Registered: Sep 2003
Posts: 1790
Quote: Ok this is getting interesting :) Did you verify the resulting table against some basic generator?

10 FOR I=0 TO 511
20 X = INT((X*X)/4)
30 XH = INT(X/256)
40 XL = X - (XH*256)
50 POKE 8192+I,XL
60 POKE 8704+I,XH
70 NEXT


No, but against a c-program.
Quick and dirty. ;)

Note also that the code is not in zeropage. If I put it there it will be shorter ofcourse, but that would be cheating in this case, no?

int main(int argc, char *argv[])
{
    int i;
    FILE *fp;

    fp=fopen("bin","wb");
    fputc(0x00,fp);
    fputc(0xc8,fp);
    for (i=0; i<512; ++i) {
        int a;
        a=i*i/4;
        fputc((a&0xff),fp);
    }
    for (i=0; i<512; ++i) {
        int a;
        a=i*i/4;
        fputc(((a>>8)&0xff),fp);
    }
    fclose(fp);
}

2005-10-17 16:47
Graham
Account closed

Registered: Dec 2002
Posts: 990
Nopes, no zeropage ofcourse. Hmm 39 bytes is really hard to believe, I managed to do it in 52 bytes now, or 51 if I use LAX #$00 (which is unstable on C128DCR).
2005-10-17 16:52
tlr

Registered: Sep 2003
Posts: 1790
Quote: Nopes, no zeropage ofcourse. Hmm 39 bytes is really hard to believe, I managed to do it in 52 bytes now, or 51 if I use LAX #$00 (which is unstable on C128DCR).

I use no undocumented opcodes either. Tell me when you want to have a look at it.
We should probably wait a little while more though. There might come someone else with a 30 byte version. ;)
2005-10-17 17:18
Graham
Account closed

Registered: Dec 2002
Posts: 990
Ok 43 bytes now here... getting closer :)
2005-10-17 17:27
tlr

Registered: Sep 2003
Posts: 1790
Quote: Ok 43 bytes now here... getting closer :)

:)

I just noticed I don't clear the decimal mode flag, but I'm guessing you don't either, right?

I wonder how different our routines can be if they are this close in size? It will be very interresting to compare.
2005-10-17 17:30
Graham
Account closed

Registered: Dec 2002
Posts: 990
Nopes, don't clear the decimal flag either. BTW: 38 bytes now :)
2005-10-17 17:39
tlr

Registered: Sep 2003
Posts: 1790
Quote: Nopes, don't clear the decimal flag either. BTW: 38 bytes now :)

Ok... time to get back to the code then! ;) Good thing I have fresh coffee!
2005-10-17 18:01
Graham
Account closed

Registered: Dec 2002
Posts: 990
37 bytes...
2005-10-17 18:06
Graham
Account closed

Registered: Dec 2002
Posts: 990
36...
2005-10-17 18:20
tlr

Registered: Sep 2003
Posts: 1790
Quote: 36...

You're scaring me... :) You are not depending on basic or kernal, are you?
2005-10-17 18:23
Graham
Account closed

Registered: Dec 2002
Posts: 990
No basic or kernal used :)
2005-10-17 18:29
tlr

Registered: Sep 2003
Posts: 1790
37 bytes... :) Must think out of the box, must think out of the box...
2005-10-17 18:31
Graham
Account closed

Registered: Dec 2002
Posts: 990
I have to leave soon, should I post the 36 byte version?
2005-10-17 18:37
tlr

Registered: Sep 2003
Posts: 1790
Sure! I'll post my 37 byte version, we can compare for fun, and someone else may shorten them further. ;)
2005-10-17 18:39
Graham
Account closed

Registered: Dec 2002
Posts: 990
Ok here it is:
ldx #$00
      txa        ; LAX #$00 would save one extra byte.
      .db $c9
lb1:  tya
      adc #$00
ml1:  sta multabhi,x
      tay
      cmp #$40
      txa
      ror
ml9:  adc #$00
      sta ml9+1
      inx
ml0:  sta multablo,x
      bne lb1
      inc ml0+2
      inc ml1+2
      clc        ; Possible to remove this somehow?
      iny
      bne lb1

2005-10-17 18:40
tlr

Registered: Sep 2003
Posts: 1790
My mul-table: 37 bytes (excuding rts)
C000   A9 00      LDA #$00
C002   A8         TAY
C003   AA         TAX
C004   C8         INY
C005   D0 06      BNE $C00D
C007   EE 15 C0   INC $C015
C00A   EE 1A C0   INC $C01A
C00D   18         CLC
C00E   69 00      ADC #$00
C010   90 01      BCC $C013
C012   E8         INX
C013   99 FF C1   STA $C1FF,Y
C016   48         PHA
C017   8A         TXA
C018   99 FF C3   STA $C3FF,Y
C01B   98         TYA
C01C   4A         LSR A
C01D   68         PLA
C01E   B0 E4      BCS $C004
C020   EE 0F C0   INC $C00F
C023   D0 DF      BNE $C004
C025   60         RTS

2005-10-17 18:42
tlr

Registered: Sep 2003
Posts: 1790
Actually they are extremly different! :)

BTW, in my code multablow is $c200, and multabhighi $c400.

Thank you for the excellent competition! :)
2005-10-17 18:48
Graham
Account closed

Registered: Dec 2002
Posts: 990
Yupz, hard competition :) indeed quite different. I thought they'd look quite similar but they don't. Maybe there is a way to save another byte then... Anyway it was a good idea to do this compo, since without you doing the 42-39 byte versions I would not have investigated any more and just assumed that 53 bytes is the limit :)
2005-10-17 19:01
Tch
Account closed

Registered: Sep 2004
Posts: 512
*imitating a crowd going berzerk*
Wohoo...we want more..heehaaaw!!!
2005-10-17 19:23
Scout

Registered: Dec 2002
Posts: 1570
There's a dutch word for all of this: "bitneuken" :)
---
-= Silicon Ltd. =-
http://forum.siliconlimited.com
2005-10-17 19:44
Bastet

Registered: Jul 2005
Posts: 88
You are nuts! ;)
2005-10-17 20:19
Trash

Registered: Jan 2002
Posts: 122
Quote: Ok this is getting interesting :) Did you verify the resulting table against some basic generator?

10 FOR I=0 TO 511
20 X = INT((X*X)/4)
30 XH = INT(X/256)
40 XL = X - (XH*256)
50 POKE 8192+I,XL
60 POKE 8704+I,XH
70 NEXT


I atleast solved that basiclist in 18 bytes...

LDA #0
TAX
STA L, X
STA L + 256, X
STA H, X
STA H + 256, X
INX
BNE * - 13

:-/
2005-10-18 00:11
raven
Account closed

Registered: Jan 2002
Posts: 137
For converting that Basic prog correctly, the winner
is Trash ;)

I'm still stuck at 36 and my vision is getting
fuzzy so time for sleep..
2005-10-18 06:22
Oswald

Registered: Apr 2002
Posts: 5094
trash, how does your TAX do X = INT((X*X)/4), then store separate lo/hi byte by the same A value ?
2005-10-18 07:54
WVL

Registered: Mar 2002
Posts: 902
Quote: trash, how does your TAX do X = INT((X*X)/4), then store separate lo/hi byte by the same A value ?

read graham's basic list again :)
2005-10-18 08:26
Trash

Registered: Jan 2002
Posts: 122
Quote: trash, how does your TAX do X = INT((X*X)/4), then store separate lo/hi byte by the same A value ?

Since cbm-basic initializes all variables to zero X=INT((X*X)/4) will always be zero therefore we can use a constant instead...
2005-10-18 08:33
Oswald

Registered: Apr 2002
Posts: 5094
this is not my day
2005-10-18 09:36
WVL

Registered: Mar 2002
Posts: 902
Quote: this is not my day

now guess how Graham feels :)
2005-10-18 11:28
Graham
Account closed

Registered: Dec 2002
Posts: 990
Trash: Basic only initializes when the variable is not already defined. Do X=<whatever> before RUN and constant 0 will not help you :P
2005-10-18 12:15
Bastet

Registered: Jul 2005
Posts: 88
Look closer at that basic listing, Graham...
Does X increase? 'fraid it dosnt, so you can easily assume that x=0 *g*
2005-10-18 12:25
Bastet

Registered: Jul 2005
Posts: 88
That will work out of the box:
1FORX=0TO511:Y=INT((x*x)/4)
2POKE8704+X,INT(y/256):POKE8192+X,Y-(PEEK(8704+x)*256):NEXTX


Thats 80 byte of basic code, tokenized and with header and footer of a standard file. *g*
Runs slow as hell but it works
2005-10-18 12:35
enthusi

Registered: May 2004
Posts: 677
I was indeed considering to try to cut it a bit by using some kernal-mul-routine-call (as not beeing forbidden) but that was about the 54 byte version. 36 is out of the question :(
Too bad. But cudos for this nice fast challenge.
Next time please announce it before everyone else leaves to vacation or something so Im left alone with it for a looong time :)
2005-10-18 13:42
Graham
Account closed

Registered: Dec 2002
Posts: 990
@BastetFurry: Yeps X increases... For example, if you do X=16 before RUN, you'll have 16*16/4 = 64 and then 64*64/4 = 1024 etc.
2005-10-18 15:22
TNT
Account closed

Registered: Oct 2004
Posts: 189
RUN clears all variables. You can circumvent that with GOTO <first_line> tho.
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Scrap/Genesis Project
leonofsgr/Singular C..
Didi/Laxity
slimeysmine
Genius/Xenon
WVL/Xenon
A3/AFL
Guests online: 115
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 The Demo Coder  (9.6)
6 Edge of Disgrace  (9.6)
7 What Is The Matrix 2  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.7)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 X-Mas Demo 2024  (9.5)
7 Dawnfall V1.1  (9.5)
8 Rainbow Connection  (9.5)
9 Onscreen 5k  (9.5)
10 Morph  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Censor Design  (9.3)
5 Triad  (9.3)
Top Logo Graphicians
1 t0m3000  (10)
2 Sander  (9.8)
3 Mermaid  (9.5)
4 Facet  (9.4)
5 Shine  (9.4)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.081 sec.