Jump to content
IGNORED

Atari_Ace's Blog - APX Pascal Architecture, part two


RSS Bot

Recommended Posts

In the last post, we worked through layers of the APX Pascal runtime to find the main interpreter loop, which in fact resides entirely in page zero. In this post, we're going to dig into some of the opcodes to get a flavor for the runtime implementation.

As we discussed last time, the each opcode is represented by a JMP value in a 512-byte table that is copied into $1D00 when the runtime starts. If you peruse though the table, the most common JMP target is $B9B5, in 81 entries. This is the not-implemented opcode, hitting any of these in code would be an error. The code seems to be an infinite loop.


AA7A: A8                TAYAA7B: BD 00 06          LDA $0600,XAA7E: E8                INXAA7F: E8                INXAA80: 4A                LSR AAA81: B0 03             BCS $AA86AA83: 98                TYAAA84: 90 DF             BCC $AA65AA86: A9 02             LDA #2AA88: 4C 92 00          JMP $0092
This pulls the top of data stack (the stack is at $0600 and indexed by X), if it's odd we're done, otherwise we call the branch function above. So it's a conditional branch.

Both of these codes are very odd. The only reason I can think of to encode part of the branch offset into the opcode is to extend the range beyond 256 bytes, but in that case, why not just have a separate opcode for long branches. Also, using both BCC and BCS isn't optimal. A little thought shows removing the BCS achieves the same result, but faster. In general the runtime code looks like it could have used a little more optimization. This project started out as a port from the 8080, perhaps the author never developed enough 6502 experience to tighten up the code in the time allowed.

The next two routines are similar:
A8EC: 29 0F             AND #$0FA8EE: A8                TAYA8EF: B1 B6             LDA ($B6),YA8F1: C8                INYA8F2: CA                DEXA8F3: CA                DEXA8F4: 9D 00 06          STA $0600,XA8F7: B1 B6             LDA ($B6),YA8F9: 9D 01 06          STA $0601,XA8FC: 4C 9D 00          JMP $009D
Both of these routine move a value to the top of the stack, just using different pointers to source the value ($C6 and $B6).

Most of the remaining of the opcodes have unique implementations. Some of the interesting ones to look at are "load string" ($2C at $A88F), load small constants ($F0-$F7), load 1, 2 and 4 bytes ($24, $25, $26), call ($A2 at $AB2C) and return ($A6 at $AC96). What's most interesting to me is that having identified these, you might notice they don't match the "Functional Specification" (
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...