Talk:MOS Technology 6502/Archives/2016

Latest comment: 7 years ago by GliderMaven in topic Power Requirements

Pronunciation

Who says it's supposed to be pronounced "sixty-five oh two"? I'll pronounce it any way I want - its a number. — Preceding unsigned comment added by 110.174.108.101 (talk) 06:57, 16 August 2014 (UTC)

I agree that "sixty-five-oh-two" isn't the only way, most I know call it the "six-five-oh-two" so that comment should be removed from the article. But untold numbers of engineers have used just one of these two for over 35 years so a convention *has* been established. You don't pronounce it any way you want though, you adhere to pre-taught conventions to ease conversation with others so please don't demand freedom that you don't need. It's not a numerical quantity, it's used as a proper noun for this microprocessor. Try calling a 7432 logic IC a "seven--forty-three--two" in conversation and see how sharply you get stopped: everyone says "seven-four" or "seventy-four" something. The article is trying to inform typical usage, incorrectly. It should still be scrubbed. — Preceding unsigned comment added by ToaneeM (talkcontribs) 09:37, 30 April 2015 (UTC)

Retracting my previous point, I don't think that the comment has to be scrubbed from the article. But I maintain the two pronunciations of "six-five-oh-two" "sixty-five-oh-two" are the two and should stay.

Buggy example code

The code that is supposed to move a block of memory is buggy in two was because SRC's and DST's high bytes are increased when the Y register (i.e. the counter) turns zero - this only works when the counter is a multiple of $100. Once this is fixed, I'm not sure whether SRC's and DST's high bytes can then be increased at the same time as their overflow may be different from each other and from the counter. — Preceding unsigned comment added by 87.151.165.189 (talk) 23:36, 3 October 2014 (UTC)

The original sample was uploaded by Loadmaster on 1 June 2013 and corrected on 16 June 2013. [1] A lot of random users have hacked at it since then. -- SWTPC6800 (talk) 01:24, 4 October 2014 (UTC)
The purpose of the example code is to illustrate to the reader what 6502 assembler source code and opcodes actually look like. Also note that code need not be optimized, for the same reason. In other words, feel free to correct the code, but don't be obsessive about the operational details of it. — Loadmaster (talk) 20:06, 8 October 2014 (UTC)

It's still buggy, very buggy. I'll try to rewrite it when I am at a desxktop Si Trew (talk) 17:58, 26 February 2016 (UTC)

I changed the wording to say a buggy implementation that attempts to copy, that was reverted. I've thus removed the whole section, because if it is saying it is an implementation of memcpy – well it is, but a buggy one – then that is misleading our readers. WP:RS please if it is added back; or talk to me. I have coded up an example that actually works while attempting to keep the brevity of the original. Si Trew (talk) 16:57, 27 February 2016 (UTC)

Please, by all means, add your code example to the article. It's my hope that *every* CPU article can have a small sample code example. — Loadmaster (talk) 20:52, 5 April 2016 (UTC)

Example removed

I see User:Loadmaster added a small example code on June 1, 2013, [2], and it was reverted today [3] by User:SimonTrew, with comment "RM sectiion, buggy code. Please provide a source and RS if inserting an example of what purports to be a memcpy routine". I've not looked at it in detail, but I do think short examples are useful. So if anyone wants to sort this out, whether the current or original versions are correct, or a better short example can be found, I offer this reminder here of what was removed. Tom Ruen (talk) 17:55, 27 February 2016 (UTC)

I have written a non-buggy example but my sodding laptop has not got the example I written with the opcodes in it. Here it is so far, to show my good faith:

          SRC = $80
          DST = SRC+2
          CNT = DST+2
                  
          ORG $0400

A2 00 MEMCPY LDY #0  ; Y = the number of bytes to copy this chunk; 0=256=the whole chunk

                  LDX CNT+1    ; X = the number of 256-byte chunks left
                  BNE LOOPCH   ; Not the last chunk? Copy whole chunk
          LASTCH  LDY CNT      ; Copy remaining bytes from last chunk
                  BNE LOOPCH   ; if X=Y=0, there is nothing left to copy
                  RTS          ; Done
Loop to copy Y bytes (0=256) from SRC to DST. We have a separate case
for Y=0 to keep the main copy loop as tight as possible. See Duff's device.
An equivalent, simpler version is two bytes shorter at the expense of 3 cycles
per iteration
LOOPCH DEY
LDA (SRC),Y
STA (DST),Y
CPY #0  ; Optimized version eliminates this 3-cycle compare
BNE LOOP

MOVCH LDA (SRC),Y

      STA (DST),Y

LOOPCH DEY

      BNE MOVCH
      LDA (SRC),Y ; For Y=0
      STA (DST),Y
Get ready for next pass
      INC SRC+1    ; Get ready for next chunk
      INC DST+1
      CPX #0       ; Was this the last chunk?
      BEQ LASTCH   ; Yes, copy remaining bytes from last chunk (if any)
      DEX          ; X is the number of whole chunks left
      CLC          ; Unconditional JMP to loop; Y=0
      BCC LOOPCH   ; Use relative addressing so routine is relocatable


I have made this somewhat better because I don't want to, e.g., do the optimisation of the relative jump of CLC/BCC at the end which takes the same number of bytes but fewer cycles and is relocatable – I have a version that has all the opcodes listed which I have hand-assembled and run through a simulator.

I appreciate that it is an example, but it should be a correct example, I think. I've only assembled mine, not tested it. Si Trew (talk) 18:22, 27 February 2016 (UTC)

Incidentally the routine could add back CNT+1 to SRC+1 and DST+1 before the RTS to restore their values; however it is handy that at exit CNT can point to the end of the bytes copied as a half-open range which could be useful for a subsequent copy. Si Trew (talk) 18:29, 27 February 2016 (UTC)
Also I think indirect Y addressing takes 6 cycles normally, but 7 if addition of Y crosses a page boundary - which will be true half the time (on average) with this implementation; a better implementation (like strcpy in the GCC distribution of C libraries, but not strncmp, at least not ten years ago) will hedge up to a decent boundary then copy quickly (even with just bytes copied, rather than double bytes or quadruple bytes, it saves two cycles each time around the loop at the expense of more work to do the fiddling fore and aft, which I assume we are not trying to show here). Let alone that this assumes that the source and destination do not overlap... I appreciate that is not the point of a general memmove; f'rexample memcpy makes no guarantees of that in C. Si Trew (talk) 18:48, 27 February 2016 (UTC)

Blatantly removing an entire section without some discussion beforehand is not proper WP etiquette. I provided the example code to illustrate to most interested readers what 6502 assembly code actually looks like, just like I did for various other processors. It's not critically important that the code be efficient or even useful, but rather that it be sufficiently illustrative of typical code for the processor being discussed. Yes, the code should be correct, inasmuch that the routine actually does something non-trivial. Perhaps I was a bit ambitious trying to write up a general memcpy routine on such a limited architecture; but any reasonably non-trivial example will do. As for sources, we certainly do not need to cite any particular external source just to provide a simple assembly language routine for this article. I wrote it and generated the opcodes myself (probably using an online 6502 emulator, of which several such websites are available). If anyone is concerned that any given memcpy routine won't pass muster, then I suggest providing a simpler example. But not providing some example code in an article about a CPU seems like a major omission for an encyclopedic article. — Loadmaster (talk) 21:02, 29 February 2016 (UTC)


The proposed replacement above is also buggy -- it loops infinitely for a copy 0 < len < 256 bytes. Tested under emulation. This occurs because it attempts to reuse the main copy loop for the final partial page, but there is no mechanism for it to exit again after doing so. I recommend adapting the version from this older revision: https://en.wikipedia.org/w/index.php?title=MOS_Technology_6502&oldid=622480872

It was reverted for style, but appears to be correct. Would be good to get a second confirmation before putting it back in, given the history of code samples on this page. I've repeated it below with opcodes from an assembler listing to save whoever does that some time. It is slightly weird in that it does an ascending copy by pages and a descending copy within pages, and calls within itself to reuse the same copy loop. That said, it correctly does nothing for CNT=0, copies only a partial page for CNT < 256, and does whole page copies + final page for CNT >= 256.

                         ; memcpy --
                         ; Copy a block of memory from one location to another.
                         ;
                         ; Entry parameters
                         ;      src - Address of source data block
                         ;      dst - Address of target data block
                         ;      cnt - Number of bytes to copy

                                 org     $0040   ; parameters at $0040
0040 00 00               src     dw      $0000
0042 00 00               dst     dw      $0000
0044 00 00               cnt     dw      $0000

0046                             org     $600    ; code at $0600
0600                     memcpy
0600 A6 45                       ldx     cnt+1
0602 F0 0C                       beq     memcpy_lastpage
0604 A0 00                       ldy     #0
0606                     memcpy_page
0606 20 14 06                    jsr     memcpy_loop
0609 E6 41                       inc     src+1
060B E6 43                       inc     dst+1
060D CA                          dex
060E D0 F6                       bne     memcpy_page
0610                     memcpy_lastpage
0610 A4 44                       ldy     cnt
0612 F0 08                       beq     memcpy_return
0614                     memcpy_loop
0614 88                          dey
0615 B1 40                       lda     (src),y
0617 91 42                       sta     (dst),y
0619 98                          tya
061A D0 F8                       bne     memcpy_loop
061C                     memcpy_return
061C 60                          rts

Regarding other comments: in a copy routine like this, modifying the high byte of the pointer variables and having non-relocatable code are both idiomatic 6502, and IMO should be left as-is. 24.130.133.67 (talk) 04:57, 19 April 2016 (UTC)

Example code, version 2

I added a short subroutine called TOLOWER in a new (resurrected) "Example code" section. It's short and sweet, and illustrates the immediate and indirect zero-page addressing modes of the 6502. — Loadmaster (talk) 17:49, 6 May 2016 (UTC)

Code fails with high bit characters due to signed overflow. The checks should use BCC/BCS instead of BMI/BPL. 24.130.133.67 (talk) 06:42, 21 May 2016 (UTC)

Power Requirements

My recollection of the 650x family is that the most remarkable characteristic of this processor was a phenomenally low power consumption, and broad voltage tolerance. I believe the specs on a 6503 I had but never hooked up were that it would run on under 2V and needed something like 2 mA. This made these CMOS processors applicable for a range of applications the other technologies could not touch. However, I don't have the specs at hand any more. I would hate for this aspect of these processors to be forgotten. Tomligon (talk) 01:19, 20 July 2016 (UTC)

The original processor was not massively low power about 400-800 mW. But the 65C02 was much lower power, about a mW. Datasheets are available if you google them.GliderMaven (talk) 01:45, 20 July 2016 (UTC)