Hi, I am curious why the MVN instruction decrements C until it rolls under to $FFFF instead of stopping at zero. I know many programming languages increment loop counters until they are one past the last valid value in a for loop, so maybe it's something like that.
Is there a hardware reason for this? The way it works, according to Eyes & Lichty, seems to be that you need to put the # of bytes to move minus 1 into C, not simply the # of bytes.
# of bytes to move minus 1?
Re: # of bytes to move minus 1?
jeffythedragonslayer wrote:
Hi, I am curious why the MVN instruction decrements C until it rolls under to $FFFF instead of stopping at zero. I know many programming languages increment loop counters until they are one past the last valid value in a for loop, so maybe it's something like that.
Is there a hardware reason for this? The way it works, according to Eyes & Lichty, seems to be that you need to put the # of bytes to move minus 1 into C, not simply the # of bytes.
Is there a hardware reason for this? The way it works, according to Eyes & Lichty, seems to be that you need to put the # of bytes to move minus 1 into C, not simply the # of bytes.
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: # of bytes to move minus 1?
jeffythedragonslayer wrote:
Hi, I am curious why the MVN instruction decrements C until it rolls under to $FFFF instead of stopping at zero. I know many programming languages increment loop counters until they are one past the last valid value in a for loop, so maybe it's something like that.
Is there a hardware reason for this? The way it works, according to Eyes & Lichty, seems to be that you need to put the # of bytes to move minus 1 into C, not simply the # of bytes.
Is there a hardware reason for this? The way it works, according to Eyes & Lichty, seems to be that you need to put the # of bytes to move minus 1 into C, not simply the # of bytes.
I see Gordon replied and echoed my thoughts. It's likely the internal logic needed to determine when terminal count has been reached was simpler by having all bits in .C flipped to 1 at the end. So, yes, .C has to be loaded with the COUNT - 1, which means COUNT = 0 will copy one byte.
Note that MVN and MVP, unlike all other instructions, can be interrupted. That being the case, it is essential that your interrupt service routine (ISR) exactly preserve the microprocessor's state and exactly restore it when interrupt servicing has completed. Otherwise the copy operation will likely go off the rails when the ISR returns control to the foreground.
The front end I use in my ISR is:
Code: Select all
rep #%00110000 ;16-bit everything
phy ;preserve MPU state
phx
pha
phb
phd
...program continues...The return is:
Code: Select all
rep #%00110000 ;16-bit everything
pld ;restore MPU state
plb
pla
plx
ply
rtiThe above methods work because when RTI is executed the status register (SR) will be pulled, putting all the flags back the way they were when the interrupt was serviced. Since the m and x flags in SR determine register sizes, the pulling of SR when RTI is executed will automatically set the registers to whatever size they were before the interrupt.
Another "quirk" of MVN and MVP is they tinker with DB, setting it to the destination data bank. Therefore is wise to push DB before the copy and then pull it afterwards to put things back in order:
Code: Select all
rep #%00110000 ;16-bit everything
lda #count-1 ;bytes to copy -1
ldx #source & $FFFF ;source address LSW
ldy #dest & $FFFF ;destination address LSW
phb ;protect current data bank
mvn #source,dest ;execute copy
plb ;back to current data bank
...program continues...The official WDC assembly language syntax for MVN and MVP has the full 24-bit source and destination addresses as the operands. The WDC assembler performs <address> >> 16 to extract the banks. In the Kowalski assembler, only the banks are used as the operands. The WDC syntax is more logical in terms of how the programmer would think about the source and destination, but the Kowalski syntax is easier for the assembler to parse. In a 65C816 machine language monitor, only the banks would be assembled with the instruction.
x86? We ain't got no x86. We don't NEED no stinking x86!
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: # of bytes to move minus 1?
drogon wrote:
...one is that it might take less logic to detect bit 15 of the counter going from 0 to 1 than to test for bits 0:15 = 0...
That seems likely.
Quote:
...also if it were the exact number of bytes then you would not be able to move 65536 bytes without needing a 17-bit register.
If MVN/MVP had been designed to use the exact count I supposed setting the initial count to $0000 would give you the full 64 KB copy when .C returned to $0000. However, bit 15 flipping from 0 to 1 is an easy test.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: # of bytes to move minus 1?
Welcome, jeffythedragonslayer!
As for your question, I think WDC simply provided what the programmer would want. As Gordon noted, C is a register with only 16 bits, and that means a choice had to be made. So, just ask yourself which seems more useful. Would you rather have...
As for the screen name you've chosen for yourself, jeffythedragonslayer seems intended to resonate with Buffy the Vampire Slayer -- is that right?
For me, that's somewhat interesting and amusing, given that my own handle -- a nickname I acquired as a teenager -- is intended to resonate with Dr Jekyll from Robert Louis Stevenson's Strange Case of Dr Jekyll and Mr Hyde.
-- Jeff
As for your question, I think WDC simply provided what the programmer would want. As Gordon noted, C is a register with only 16 bits, and that means a choice had to be made. So, just ask yourself which seems more useful. Would you rather have...
- a minimum move of 0 bytes and a maximum move of $FFFF bytes, or
a minimum move of 1 bytes and a maximum move of $10000 bytes ?
As for the screen name you've chosen for yourself, jeffythedragonslayer seems intended to resonate with Buffy the Vampire Slayer -- is that right?
For me, that's somewhat interesting and amusing, given that my own handle -- a nickname I acquired as a teenager -- is intended to resonate with Dr Jekyll from Robert Louis Stevenson's Strange Case of Dr Jekyll and Mr Hyde.
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
-
jeffythedragonslayer
- Posts: 114
- Joined: 03 Oct 2021
Re: # of bytes to move minus 1?
Thank you for your enlightening replies. It's a nickname a friend game me in high school - I've never asked him if it had anything to do with Buffy.