ChatGPT: "Write a multiplication function in 6502 assembly"

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
WillisBlackburn
Posts: 52
Joined: 14 Aug 2021

ChatGPT: "Write a multiplication function in 6502 assembly"

Post 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
User avatar
Proxy
Posts: 746
Joined: 03 Aug 2018
Location: Germany

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post 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
WillisBlackburn
Posts: 52
Joined: 14 Aug 2021

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post 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?"
User avatar
Proxy
Posts: 746
Joined: 03 Aug 2018
Location: Germany

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post 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?"
Martin_H
Posts: 837
Joined: 08 Jan 2014

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post 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.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post 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:
Quote:
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.)
Last edited by BigEd on Tue Dec 20, 2022 8:24 am, edited 1 time in total.
teamtempest
Posts: 443
Joined: 08 Nov 2009
Location: Minnesota
Contact:

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post by teamtempest »

Quote:
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.
ChrisChiesa
Posts: 1
Joined: 05 Feb 2023

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post 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. :-)
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post 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
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post by GARTHWILSON »

barnacle wrote:
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.
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?
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: ChatGPT: "Write a multiplication function in 6502 assemb

Post 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
Post Reply