Re: Error in 64doc.txt at Bo's site?

From: Segher Boessenkool <segher_at_kernel.crashing.org>
Date: Wed, 19 Sep 2018 10:30:14 -0500
Message-ID: <20180919153013.GZ23155@gate.crashing.org>
On Wed, Sep 19, 2018 at 04:26:24PM +0200, Ruud@Baltissen.org wrote:

[ some html email, which is hard to reply to... ]

Ah, jsr, one of the most interesting instructions :-)

The address stored is the address of the next insn minus one, i.e. the
address of the jsr plus two.

>  1 PC R fetch opcode, increment PC
>  2 PC R fetch low address byte, increment PC
>  3 $0100,S R internal operation (predecrement S?)
>  4 $0100,S W push PCH on stack, decrement S
>  5 $0100,S W push PCL on stack, decrement S
>  6 PC R copy low address byte to PCL, fetch high address
>  byte to PCH
>  What I read is: at step 1 and 2 the Program Counter is increased and thus
>  points to the next instruction at step 4. So this is the address that is
>  pushed to the stack at step 4 and 5.
>  But IMHO the PC is only incremented once before pushed to the stack. When
>  RTS is executed, the stored address is read, written into the PC and
>  increased according this document. Which prooves the incremental at step 2
>  is wrong.

That's not what the CPU really does.  It does:

00100000  jsr
2  S->ADL->ABL  1->ADH->ABH  DL->S  ADL->
3  ->ADL->ABL  PCH->DB  WR  ADL-1->
4  ->ADL->ABL  PCL->DB  WR  ADL-1->
5  fetch  ->
0  ->S, S->ADL->ABL,PCL  DL->ADH->ABH,PCH

(and at 0 and 1 there are fetches, as for everything).  Your cycles start
counting at 1.

>  1 PC R fetch opcode, increment PC
>  2 PC R fetch low address byte, increment PC

These are correct, of course.

>  3 $0100,S R internal operation (predecrement S?)

2  S->ADL->ABL  1->ADH->ABH  DL->S  ADL->

Save the low address fetched (in the previous cycle) to S; the actual
stack pointer is copied to ADL, which is also needed for actually
addressing the stack (in later cycles).  There is no "predecrement".
ADL (i.e. the stack pointer) is moved to the ALU output, the "holding
register", which is the only non-architected dataflow reg in the whole
CPU.

>  4 $0100,S W push PCH on stack, decrement S

3  ->ADL->ABL  PCH->DB  WR  ADL-1->

And here that ALU output is moved to the low address byte.  PCH is written
to that address.  ADL is decreased, that is the ALU output.

>  5 $0100,S W push PCL on stack, decrement S

4  ->ADL->ABL  PCL->DB  WR  ADL-1->

And analogous with PCL.

>  6 PC R copy low address byte to PCL, fetch high address byte to PCH

5  fetch  ->

Fetch the data byte, and retain the value in the ALU output.

0  ->S, S->ADL->ABL,PCL  DL->ADH->ABH,PCH

Every instruction ends with phases 0 and 1, which overlaps the fetches
of the next insn's first two bytes (so it does nothing on the external
buses).

Move the ALU output (from the previous cycles) to the S register (it now
has been decreased twice).  At the same time, move what was in S (which
is the low dest address fetched) to the low address bus and PCL, and
move what was fetched in the previous cycles (the high dest address) to
the high address bus and PCH.  This is the address that we fetch from
for the next insn.

Let me paste the stuff for rts too, without explanation:

01100000  rts
2  S->ADL->ABL  1->ADH->ABH  ADL+1->
3  ->ADL->ABL  ADL+1->
4  ->ADL->ABL, ->S  DL->
5  ->ADL->ABL  DL->ADH->ABH

Pretty :-)


Segher
Received on 2018-09-19 21:00:05

Archive generated by hypermail 2.2.0.