• Typo in ProDOS refTechMan

    From Colin Leroy-Mira@21:1/5 to All on Tue Aug 22 22:19:45 2023
    Hi everyone,

    I think there's a typo in the ProDOS Technical Reference Manual at http://www.easy68k.com/paulrsm/6502/PDOS8TRM.HTM#4.2

    In fact, "Upon completion of the call, the MLI returns to the address
    of the JSR plus 6" - not 3.

    Unless I'm mistaken.

    HTH,
    --
    Colin
    https://www.colino.net/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jerry Penner@21:1/5 to Colin Leroy-Mira on Tue Aug 22 22:49:46 2023
    Colin Leroy-Mira <colin@colino.net> writes:

    Hi everyone,

    I think there's a typo in the ProDOS Technical Reference Manual at http://www.easy68k.com/paulrsm/6502/PDOS8TRM.HTM#4.2

    In fact, "Upon completion of the call, the MLI returns to the address
    of the JSR plus 6" - not 3.

    Unless I'm mistaken.

    HTH,

    I think you're right. What ProDOS does is add 3 bytes to the return
    address to pass over the command-number and command-list-address, but
    the effect is that execution continues 6 bytes after the start of the
    JSR instruction. I have read that page many times and never noticed
    that, probably because I understood what was going on with the
    return-address.

    Nice catch.

    --
    --
    Jerry jerry+a2 at jpen.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Colin Leroy-Mira@21:1/5 to All on Wed Aug 23 08:23:11 2023
    Hi,

    I think you're right. What ProDOS does is add 3 bytes to the return
    address to pass over the command-number and command-list-address, but
    the effect is that execution continues 6 bytes after the start of the
    JSR instruction. I have read that page many times and never noticed
    that, probably because I understood what was going on with the >return-address.

    I only noticed it because I couldn't see it returning by looking for
    its return point when adding 3 to the address where it was called :)
    --
    Colin
    https://www.colino.net/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Oliver Schmidt@21:1/5 to Colin Leroy-Mira on Wed Aug 23 07:38:54 2023
    Colin Leroy-Mira <colin@colino.net> wrote:
    Hi,

    I think you're right. What ProDOS does is add 3 bytes to the return
    address to pass over the command-number and command-list-address, but
    the effect is that execution continues 6 bytes after the start of the
    JSR instruction. I have read that page many times and never noticed
    that, probably because I understood what was going on with the
    return-address.

    I only noticed it because I couldn't see it returning by looking for
    its return point when adding 3 to the address where it was called :)

    I - pretty strongly - disagree. What JSR does is an implementation detail.
    What the documentation wants to express is that MLI returns 3 bytes
    "behind" what a "bare" JSR returns to. Putting a 6 there instead of a 3 is plainly wrong.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Colin Leroy-Mira@21:1/5 to All on Wed Aug 23 15:22:14 2023
    Hi,

    I - pretty strongly - disagree. What JSR does is an implementation
    detail. What the documentation wants to express is that MLI returns 3
    bytes "behind" what a "bare" JSR returns to. Putting a 6 there instead
    of a 3 is plainly wrong.

    I see what you mean, but the original phrasing is confusing. It could
    be "the MLI returns 3 bytes behind than a normal JSR does, to the
    address of the JSR plus 6".

    --
    Colin
    https://www.colino.net/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jerry Penner@21:1/5 to Colin Leroy-Mira on Thu Aug 24 00:06:29 2023
    Colin Leroy-Mira <colin@colino.net> writes:

    Hi,

    Oliver Schmidt <ol.sc@web.de> wrote:
    I - pretty strongly - disagree. What JSR does is an implementation
    detail. What the documentation wants to express is that MLI returns 3
    bytes "behind" what a "bare" JSR returns to. Putting a 6 there instead
    of a 3 is plainly wrong.

    I see what you mean, but the original phrasing is confusing. It could
    be "the MLI returns 3 bytes behind than a normal JSR does, to the
    address of the JSR plus 6".


    The P8 tech-ref states:

    ----------------------------------------
    SYSCALL JSR MLI ;Call Command Dispatcher
    DB CMDNUM ;This determines which call is being made
    DW CMDLIST ;A two-byte pointer to the parameter list
    BNE ERROR ;Error if nonzero

    Upon completion of the call, the MLI returns to the address of the
    JSR plus 3 (in the above example, the BNE statement); the call
    number and parameter list pointer are skipped. ----------------------------------------

    Where the CPU returns to is 6 bytes past the label SYSCALL, which is the location of the "BNE ERROR" instruction.

    I think I always read and understood the book the way I think Oliver
    does, but I think the book's address arithmetic is wrong, looking at it
    now.

    --
    --
    Jerry jerry+a2 at jpen.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeff Blakeney@21:1/5 to Jerry Penner on Thu Aug 24 08:10:11 2023
    On 2023-08-24 2:06 a.m., Jerry Penner wrote:
    Colin Leroy-Mira <colin@colino.net> writes:

    The P8 tech-ref states:

    ---------------------------------------- SYSCALL JSR MLI ;Call
    Command Dispatcher DB CMDNUM ;This determines which call is being
    made DW CMDLIST ;A two-byte pointer to the parameter list BNE
    ERROR ;Error if nonzero

    Upon completion of the call, the MLI returns to the address of the
    JSR plus 3 (in the above example, the BNE statement); the call number
    and parameter list pointer are skipped. ----------------------------------------

    Where the CPU returns to is 6 bytes past the label SYSCALL, which is
    the location of the "BNE ERROR" instruction.

    I think I always read and understood the book the way I think Oliver
    does, but I think the book's address arithmetic is wrong, looking at
    it now.
    As far as I remember my 6502 assembly, when you do a JSR, the processor
    has already read the JSR byte and the two byte address so the PC is
    pointing at the DB CMDNUM statement and that is what is pushed on the
    stack. The MLI pulls that address off the stack, adds 3 to it, pushes
    it back on the stack and does an RTS so that the BNE ERROR statement
    will get executed.

    In other words, the SYSCALL is the address of the JSR but it isn't the
    address that gets pushed onto the stack when the JSR is executed.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael J. Mahon@21:1/5 to Jeff Blakeney on Mon Aug 28 06:45:32 2023
    Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> wrote:
    On 2023-08-24 2:06 a.m., Jerry Penner wrote:
    Colin Leroy-Mira <colin@colino.net> writes:

    The P8 tech-ref states:

    ---------------------------------------- SYSCALL JSR MLI ;Call
    Command Dispatcher DB CMDNUM ;This determines which call is being
    made DW CMDLIST ;A two-byte pointer to the parameter list BNE
    ERROR ;Error if nonzero

    Upon completion of the call, the MLI returns to the address of the
    JSR plus 3 (in the above example, the BNE statement); the call number
    and parameter list pointer are skipped.
    ----------------------------------------

    Where the CPU returns to is 6 bytes past the label SYSCALL, which is
    the location of the "BNE ERROR" instruction.

    I think I always read and understood the book the way I think Oliver
    does, but I think the book's address arithmetic is wrong, looking at
    it now.
    As far as I remember my 6502 assembly, when you do a JSR, the processor
    has already read the JSR byte and the two byte address so the PC is
    pointing at the DB CMDNUM statement and that is what is pushed on the
    stack. The MLI pulls that address off the stack, adds 3 to it, pushes
    it back on the stack and does an RTS so that the BNE ERROR statement
    will get executed.

    In other words, the SYSCALL is the address of the JSR but it isn't the address that gets pushed onto the stack when the JSR is executed.

    Well, the details are: JSR pushes the address of the JSR opcode plus *two*
    on the stack, and the RTS pops the address and adds *one* to get the return
    PC value.

    This doesn’t change the need to add 3 to the stacked value to skip 3 bytes
    of in-line data, but it does mean that the stacked address points at the
    high byte of the JSR, not the first byte of the in-lined data.

    Sometimes details matter. ;-)

    --
    -michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeff Blakeney@21:1/5 to Michael J. Mahon on Mon Aug 28 08:28:25 2023
    On 2023-08-28 2:45 a.m., Michael J. Mahon wrote:
    Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> wrote:
    As far as I remember my 6502 assembly, when you do a JSR, the processor
    has already read the JSR byte and the two byte address so the PC is
    pointing at the DB CMDNUM statement and that is what is pushed on the
    stack. The MLI pulls that address off the stack, adds 3 to it, pushes
    it back on the stack and does an RTS so that the BNE ERROR statement
    will get executed.

    In other words, the SYSCALL is the address of the JSR but it isn't the
    address that gets pushed onto the stack when the JSR is executed.

    Well, the details are: JSR pushes the address of the JSR opcode plus *two*
    on the stack, and the RTS pops the address and adds *one* to get the return PC value.

    I haven't done any 6502 coding in a long time but my memory tells me the
    6502 did it this way: PC has address of SYSCALL (or probably SYSCALL-1
    and increments the PC to get there), processor reads the byte there to
    see what opcode to execute, sees it is a JSR so increments the PC and
    reads the low byte of the address, increments the PC and reads the high
    byte of the address, pushes the current PC (SYSCALL +2) to the stack,
    changes the PC to the address it just read and continues execution from
    there. When it hits an RTS it pulls the address off the stack, adds one
    to it and continues executing from there.

    This doesn’t change the need to add 3 to the stacked value to skip 3 bytes of in-line data, but it does mean that the stacked address points at the
    high byte of the JSR, not the first byte of the in-lined data.

    Sometimes details matter. ;-)

    Breaking it down above, I realized that I probably got it wrong in my
    original post and the stack gets the address of the high byte and not
    the address of the DB CMDNUM. Also it makes me wonder if the 6502
    subtracts one from the JSR address when it puts it in the PC so that it
    can be incremented before reading the opcode at the JSR address. It
    depends on whether the 6502 always increments the PC before reading the
    next opcode and my memory fails me on that point.

    As to the original question, the 6502 pushes SYSCALL + 2 to the stack,
    the MLI needs to add 3 to the address pulled off the stack, the 6502
    adds 1 when it does the RTS so you end up continuing execution at
    SYSCALL +6 in the example.

    Knowing the details of how the 6502 works in this case isn't really
    necessary, you just need to know that your code will continue executing
    after the command block. :)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From qkumba@21:1/5 to All on Mon Aug 28 10:23:09 2023
    In fact, "Upon completion of the call, the MLI returns to the address
    of the JSR plus 6" - not 3.

    It should say to the *return address* of the JSR plus 3.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Antoine Vignau@21:1/5 to qkumba on Mon Aug 28 12:29:36 2023
    On Monday, August 28, 2023 at 7:23:10 PM UTC+2, qkumba wrote:
    In fact, "Upon completion of the call, the MLI returns to the address
    of the JSR plus 6" - not 3.
    It should say to the *return address* of the JSR plus 3.

    EXACTLY! That is the only viable/correct/reliable/<insert positive adjective>/ sentence.

    Antoine

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter 'Shaggy' Haywood@21:1/5 to All on Thu Aug 31 13:30:34 2023
    Groovy hepcat Michael J. Mahon was jivin' in comp.sys.apple2.programmer
    on Mon, 28 Aug 2023 04:45 pm. It's a cool scene! Dig it.

    Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> wrote:

    In other words, the SYSCALL is the address of the JSR but it isn't
    the address that gets pushed onto the stack when the JSR is executed.

    Well, the details are: JSR pushes the address of the JSR opcode plus
    *two* on the stack, and the RTS pops the address and adds *one* to get
    the return PC value.

    Not quite. What happens is that the first byte of the instruction (the
    op code) is read and, depending on the particular code, either 0, 1 or
    2 operand bytes are read in. In the case of a JSR, 3 bytes are read in
    total, the op code and a 2 byte address operand. The program counter is
    updated as each byte is read in.
    Next, the operation is carried out. For JSR that means the current
    value of the PC, which now contains the address of the next instruction
    (or whatever occupies the memory following the JSR, including operand)
    is pushed on the stack before execution branches to the new location.
    An RTS instruction just pulls the address off the stack and bungs it
    into the PC so that execution can take up from there.

    This doesn’t change the need to add 3 to the stacked value to skip 3
    bytes of in-line data, but it does mean that the stacked address
    points at the high byte of the JSR, not the first byte of the in-lined
    data.

    No, it is the address of the next instruction. You're right about not changing the need to add 3 to the address. It's just that the address
    is that of the following op code..., which before 3 is added, in this
    case, isn't an op code but data.

    --


    ----- Dig the NEW and IMPROVED news sig!! -----


    -------------- Shaggy was here! ---------------
    Ain't I'm a dawg!!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael J. Mahon@21:1/5 to Jeff Blakeney on Thu Aug 31 18:54:03 2023
    Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> wrote:
    On 2023-08-28 2:45 a.m., Michael J. Mahon wrote:
    Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> wrote:
    As far as I remember my 6502 assembly, when you do a JSR, the processor
    has already read the JSR byte and the two byte address so the PC is
    pointing at the DB CMDNUM statement and that is what is pushed on the
    stack. The MLI pulls that address off the stack, adds 3 to it, pushes
    it back on the stack and does an RTS so that the BNE ERROR statement
    will get executed.

    In other words, the SYSCALL is the address of the JSR but it isn't the
    address that gets pushed onto the stack when the JSR is executed.

    Well, the details are: JSR pushes the address of the JSR opcode plus *two* >> on the stack, and the RTS pops the address and adds *one* to get the return >> PC value.

    I haven't done any 6502 coding in a long time but my memory tells me the
    6502 did it this way: PC has address of SYSCALL (or probably SYSCALL-1
    and increments the PC to get there), processor reads the byte there to
    see what opcode to execute, sees it is a JSR so increments the PC and
    reads the low byte of the address, increments the PC and reads the high
    byte of the address, pushes the current PC (SYSCALL +2) to the stack,
    changes the PC to the address it just read and continues execution from there. When it hits an RTS it pulls the address off the stack, adds one
    to it and continues executing from there.

    This doesn’t change the need to add 3 to the stacked value to skip 3 bytes >> of in-line data, but it does mean that the stacked address points at the
    high byte of the JSR, not the first byte of the in-lined data.

    Sometimes details matter. ;-)

    Breaking it down above, I realized that I probably got it wrong in my original post and the stack gets the address of the high byte and not
    the address of the DB CMDNUM. Also it makes me wonder if the 6502
    subtracts one from the JSR address when it puts it in the PC so that it
    can be incremented before reading the opcode at the JSR address. It
    depends on whether the 6502 always increments the PC before reading the
    next opcode and my memory fails me on that point.

    It doesn’t. Note that all the hardware vectors—IRQ, RESET, etc. are the actual service routine addresses, not the addresses minus one.

    This is in contrast with the ROM convention of “RTSing” to a routine whose address is part of a table of “routine addresses -1” to work around the lack of an indexed indirect JMP. (RTS takes its time to increment the
    return as it pops successive bytes from the stack.)

    As to the original question, the 6502 pushes SYSCALL + 2 to the stack,
    the MLI needs to add 3 to the address pulled off the stack, the 6502
    adds 1 when it does the RTS so you end up continuing execution at
    SYSCALL +6 in the example.

    Knowing the details of how the 6502 works in this case isn't really necessary, you just need to know that your code will continue executing
    after the command block. :)

    Right, but it matters a great deal to the implementor of SYSCALL, or any
    other subroutine which uses in-line parameters. ;-)

    --
    -michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael J. Mahon@21:1/5 to Peter 'Shaggy' Haywood on Thu Aug 31 18:54:04 2023
    Peter 'Shaggy' Haywood <phaywood@alphalink.com.au> wrote:
    Groovy hepcat Michael J. Mahon was jivin' in comp.sys.apple2.programmer
    on Mon, 28 Aug 2023 04:45 pm. It's a cool scene! Dig it.

    Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> wrote:

    In other words, the SYSCALL is the address of the JSR but it isn't
    the address that gets pushed onto the stack when the JSR is executed.

    Well, the details are: JSR pushes the address of the JSR opcode plus
    *two* on the stack, and the RTS pops the address and adds *one* to get
    the return PC value.

    Not quite. What happens is that the first byte of the instruction (the
    op code) is read and, depending on the particular code, either 0, 1 or
    2 operand bytes are read in. In the case of a JSR, 3 bytes are read in
    total, the op code and a 2 byte address operand. The program counter is updated as each byte is read in.
    Next, the operation is carried out. For JSR that means the current
    value of the PC, which now contains the address of the next instruction
    (or whatever occupies the memory following the JSR, including operand)
    is pushed on the stack before execution branches to the new location.
    An RTS instruction just pulls the address off the stack and bungs it
    into the PC so that execution can take up from there.

    This doesn’t change the need to add 3 to the stacked value to skip 3
    bytes of in-line data, but it does mean that the stacked address
    points at the high byte of the JSR, not the first byte of the in-lined
    data.

    No, it is the address of the next instruction. You're right about not changing the need to add 3 to the address. It's just that the address
    is that of the following op code..., which before 3 is added, in this
    case, isn't an op code but data.


    Before posting, you should have RTFM. ;-)

    That is NOT how JSR/RTS works.

    You can “pretend” that it works like that as long as you never use (or create) the return data that is pushed on the stack.

    --
    -michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Antoine Vignau@21:1/5 to All on Thu Sep 7 12:41:42 2023
    I am a big fan of http://www.brutaldeluxe.fr/documentation/cortland/v7%2065SC816%20opcodes%20Cycle%20by%20cycle%20listing.pdf

    I let you discover the opcodes, cycle by cycle listing,

    Antoine

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter 'Shaggy' Haywood@21:1/5 to All on Tue Sep 5 12:14:22 2023
    Groovy hepcat Michael J. Mahon was jivin' in comp.sys.apple2.programmer
    on Fri, 1 Sep 2023 04:54 am. It's a cool scene! Dig it.

    Peter 'Shaggy' Haywood <phaywood@alphalink.com.au> wrote:
    Groovy hepcat Michael J. Mahon was jivin' in
    comp.sys.apple2.programmer on Mon, 28 Aug 2023 04:45 pm. It's a cool
    scene! Dig it.

    Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> wrote:

    In other words, the SYSCALL is the address of the JSR but it isn't
    the address that gets pushed onto the stack when the JSR is
    executed.

    Well, the details are: JSR pushes the address of the JSR opcode plus
    *two* on the stack, and the RTS pops the address and adds *one* to
    get the return PC value.

    Not quite. What happens is that the first byte of the instruction
    (the
    op code) is read and, depending on the particular code, either 0, 1
    or 2 operand bytes are read in. In the case of a JSR, 3 bytes are
    read in total, the op code and a 2 byte address operand. The program
    counter is updated as each byte is read in.
    Next, the operation is carried out. For JSR that means the current
    value of the PC, which now contains the address of the next
    instruction (or whatever occupies the memory following the JSR,
    including operand) is pushed on the stack before execution branches
    to the new location.
    An RTS instruction just pulls the address off the stack and bungs
    it
    into the PC so that execution can take up from there.

    This doesn’t change the need to add 3 to the stacked value to skip 3
    bytes of in-line data, but it does mean that the stacked address
    points at the high byte of the JSR, not the first byte of the
    in-lined data.

    No, it is the address of the next instruction. You're right about
    not
    changing the need to add 3 to the address. It's just that the address
    is that of the following op code..., which before 3 is added, in this
    case, isn't an op code but data.


    Before posting, you should have RTFM. ;-)

    That is NOT how JSR/RTS works.

    You can “pretend” that it works like that as long as you never use (or create) the return data that is pushed on the stack.

    After doing some reading, I see that you are quite correct. I bow to
    superior knowledge and would like to say, in the words of Maxwell
    Smart, "Sorry about that, Chief!"

    --


    ----- Dig the NEW and IMPROVED news sig!! -----


    -------------- Shaggy was here! ---------------
    Ain't I'm a dawg!!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)