Page 1 of 1
ChatGPT: "Write a multiplication function in 6502 assembly"
Posted: Sat Dec 17, 2022 8:20 pm
by WillisBlackburn
Hilarious AI-generated multiplication function, presented here without further comment.
Code: Select all
; Multiply the 16-bit value in A:X by the 16-bit value in Y:B and store the result in A:X
; Input: A:X = first operand
; Y:B = second operand
; Output: A:X = product
; Y:B = undefined
multiply:
ldy #0 ; Clear Y register
sta temp_low ; Save low byte of first operand
sty temp_high ; Save high byte of first operand
stx temp_low+1 ; Save low byte of second operand
stx temp_high+1 ; Save high byte of second operand
lda #0 ; Clear A register
ldx #0 ; Clear X register
loop:
lsr temp_low+1 ; Shift right second operand
ror temp_high+1 ; Rotate through carry second operand
bcc skip ; Skip add if carry is clear
clc ; Clear carry flag
lda temp_low ; Add first operand to A
adc temp_low+1 ; Add second operand to A
sta temp_low ; Save result
ldx temp_high ; Add first operand to X
adc temp_high+1 ; Add second operand to X
stx temp_high ; Save result
skip:
inx ; Increment X register
bne loop ; Repeat until X overflows
lda temp_low ; Load result low byte
ldx temp_high ; Load result high byte
rts ; Return from subroutine
temp_low: .byte 0 ; Temporary storage for low byte of first operand
temp_high: .byte 0 ; Temporary storage for high byte of first operand
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Sat Dec 17, 2022 8:57 pm
by Proxy
i've also gotten ChatGPT to write some 6502 assembly. specifically i asked it to write a function that takes a 32-bit fixed point number and calculates the inverse (1/x) of said number.
it always got a bit confused and only made the function save the lowest byte of the result instead of the whole 32-bits. it also sometimes assumes that all registers, not just the Accumulator, can do math. so you end up with fun instructions like "ADC X, A"
but it is fairly adaptable, for example one time it somehow assumed A, X, and Y were 16-bit wide. so i told it that they were only 8-bit wide and it adjusted it's code accordingly. so if you give it a detailed description of what you want, and when noticing any obvious mistakes tell it about them, it can make some decent code.
also this is not 6502 related but i've been working on a Ray Tracer in C using OpenCL because i want to experiment with modern GPUs, so i asked ChatGPT to write a function for me to detect when a ray intersects with a triangle, giving it exact descriptions of input arguments and what i want it to return. and the function worked perfectly without any alterations... which is good because 3D math kinda goes over my head a bit
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Sun Dec 18, 2022 2:47 am
by WillisBlackburn
I didn't think to correct it. How did you do that? Can I just say, "Hey, by the way, the 6502 has no B register?"
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Sun Dec 18, 2022 7:52 am
by Proxy
yes, it is a chat. like if you were to talk to someone in this forum.
though keep in mind to be specific. so for example if it uses a MUL or DIV Instruction which obviously don't exist on the 6502 tell it "the 6502 has no MUL or DIV Instructions, can you adjust the code to exclude those?"
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Mon Dec 19, 2022 1:16 am
by Martin_H
I can pretty quickly spot stuff that looks wrong. But what I wonder is how does it come up with this code? What sort of algorithm could generate something that sort of appears reasonable but is wide of the mark.
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Mon Dec 19, 2022 7:50 am
by BigEd
It works very like a Markov chain, rather like the pastiches one would see back in the 80s or 90s, with one difference being that the generator has a very deep history, and another that the probability for the next token is based on the prompt and the output so far. Another difference is that it's trained on an enormous body of text taken mostly from the web.
The more specific the prompt, and the more popular the content, the better it will do. I would expect it would do better writing x86 code than 1802 code, for example. If the prompt mentions Commodore and quarter squares, it might do better yet.
The algorithm is terribly simple: it's the data which contains all the complexity. The advances come in being able to digest terrifically large amounts of data.
Markov chains on Usenet in 1994:
https://groups.google.com/g/comp.sys.ap ... XL8ZuHTI4J
and here from 1991
https://groups.google.com/g/soc.motss/c ... wvsdsci5gJ
In BYTE magazine November 1984
A Travesty Generator for Micros
Fred Brooks in the 1950s, as an undergrad, programming the Mark IV at Harvard:
So we undertook for our first year project to write a program that would analyze melodies and create synthetic melodies using a eightfold Markovian process. And that took us three years to get done but when—- and the problem is what do you use for a sample. What we needed is a big a corpus as we could get. So we chose common meter hymns because we could find a lot of them that already had the same metrical structure. We transposed them all to the same key then we analyzed the transition probabilities of the melodies. And the interesting question was, is there some order at which you get something that sounds like a human could have written it and yet doesn't replicate a chunk of your sample. And what we found was that at orders five and six that did happen. At seven and eight we replicated sample halves, and at two and three and so forth you wouldn't have mistaken it for human music. But at five and six we got stuff you could pass off on any choir.
Oral History of Fred Brooks; 2007-09-16
Edit: for more detail, perhaps see this article
(via
this discussion which is worth a look too especially for the illustrations of failures in simple arithmetic. If you can't always get arithmetic right, surely not a good idea to expect correct code generation.)
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Mon Dec 19, 2022 6:09 pm
by teamtempest
It works very like a Markov chain
It's a pity there's no way to upvote a post here. Interesting stuff, reminding us once again that there's not that much new under the sun.
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Sun Feb 05, 2023 7:38 pm
by ChrisChiesa
I assume we're all aware that the code won't work as shown. Two consecutive STX's, claiming to be the high and low bytes of the second operand, are all I need to see. The fact that the 6502 has no B register is almost irrelevant, since it nowhere attempts to use a B register. Still, it's probably better code, and was undoubtedly written faster, than anything I could produce by hand without a lot of retooling from forty years ago.

Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Mon Feb 06, 2023 3:49 pm
by barnacle
Heh. I've just written a 16*16 = 32 bit unsigned multiply three ways (using the stack, a data stack, and bare memory for variables) and thrown the first two away as over-complex... and I think I'm about to throw the third away too as providing more data than I need. Though it is handy for a base-2 to base-36 integer reader
Neil
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Mon Feb 06, 2023 6:47 pm
by GARTHWILSON
Heh. I've just written a 16*16 = 32 bit unsigned multiply three ways (using the stack, a data stack, and bare memory for variables) and thrown the first two away as over-complex... and I think I'm about to throw the third away too as providing more data than I need. Though it is handy for a base-2 to base-36 integer reader
Be sure to see our topic at viewtopic.php?t=689, about UM* (multiplication) bug in common 6502 Forths (and my fix). It also shows some faster variations, with code size and speed comparisons. Forum member TobyLobster has done extensive work comparing over 60 6502 integer multiply methods, and posted a great compilation here.
Re: ChatGPT: "Write a multiplication function in 6502 assemb
Posted: Mon Feb 06, 2023 9:44 pm
by barnacle
Yes, I did see that; it was what persuaded me to come up with a larger and slightly more complex multiplication than I actually need, just for the hell of it. (I could cover all my immediate use with an 8x8 = 16 I think, to index into a 60-deep table with 7-byte entries).
This is about as simple as I could come up with but the only optimisations are a fast break if either operand is zero, and a restricted loop through when the multiplicand shifts right to zero. It's not much slower than a 16x16 = 16, just a couple of extra additions per cycle.
Code: Select all
umul: ; unsigned 16x16 = 32 multiply
; multiplicand and multiplier in param_a, param_b
; result in result
; also thumps param_c as a temp
lda #0
sta result ; result = 0
sta result + 1
sta result + 2
sta result + 3
sta param_c
sta param_c + 1 ; use param_c as extension of param_b
lda param_b
ora param_b + 1 ; if MPLIER != 0
beq mul_x
mul_0:
lsr param_a + 1 ; MICAND /= 2
ror param_a
bcc mul_1 ; if MICAND & 1 == 1
clc ; MRESULT += MPLIER
lda param_b
adc result
sta result
lda param_b + 1
adc result + 1
sta result + 1
lda param_c
adc result + 2
sta result + 2
lda param_c + 1
adc result + 3
sta result + 3
mul_1:
asl param_b ; MPLIER *= 2
rol param_b + 1
rol param_c
rol param_c + 1
lda param_a
ora param_a + 1
bne mul_0 ; while MICAND != 0
mul_x:
rts
Of passing parameters: the lack of a base pointer in 6502 (as, say, an 8086 has) makes passing and manipulating data on the return stack a little tricky though sticking the stack pointer in x and indexing above that
Code: Select all
tsx
lda $103,x ; first byte above the return address
adc $105,x ; third byte above the return address
works but means that if you use the stack in the calculation, things move around relative to the current stack position. It's also simpler if the calling routine both pushes data on the stack and expects to remove the same amount of data.
Neil