Page 1 of 1

# of bytes to move minus 1?

Posted: Sun Oct 03, 2021 2:41 am
by jeffythedragonslayer
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.

Re: # of bytes to move minus 1?

Posted: Sun Oct 03, 2021 7:42 am
by drogon
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.
I don't know exactly, but I suspect 2 reasons - 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, 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.

-Gordon

Re: # of bytes to move minus 1?

Posted: Sun Oct 03, 2021 7:58 am
by BigDumbDinosaur
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.

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
         rti

The 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.

Re: # of bytes to move minus 1?

Posted: Sun Oct 03, 2021 8:05 am
by BigDumbDinosaur
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.

Re: # of bytes to move minus 1?

Posted: Sun Oct 03, 2021 2:32 pm
by Dr Jefyll
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...
  • 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. :P

-- Jeff

Re: # of bytes to move minus 1?

Posted: Mon Oct 25, 2021 2:47 am
by jeffythedragonslayer
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.