Sunday, June 17, 2018

The 65020

The original idea for the 65020 came about 30 years ago, as a reaction to the 65816's mode bits.  The 65816 is a better 6502, but it's not a very satisfying processor.  I wanted to do better. 

The key idea in the 65020 is the extension of bytes to 16 bits.  That immediately opens up a lot of possibilities.  Instructions have 8 more bits to specify data width, extra registers, and other operations.  16 bit addresses become 32 bits.

The intention is that if the top 8 bits of every byte are all zero, then it will behave exactly like a 6502.  So far I've managed to do that, with a few minor exceptions: the stack doesn't wrap, and zero-page indexing doesn't wrap either.

Instruction set

Many of the gaps in the 6502's opcode map have been filled with new instructions, and new addressing modes for old instructions:



New opcodes are marked in gray.

  • ACX, ACY: Add with carry, with an X or Y register as destination
  • SCX, SCY: Subtract with carry, with an X or Y register as destination
  • ANX, ANY: Logical and, with an X or Y register as destination
  • EOX, EOY: Logical exclusive-or, with an X or Y register as destination
  • ORX, ORY: Logical or, with an X or Y register as destination
  • MUL, DIV, MOD: Multiply, divide, and mod operations
  • SQR: Square root (if floating point is ever implemented)
  • PHX, PHY: Push an X or Y register to the stack
  • PLX, PLY: Pull an X or Y register from the stack
  • SEV: Set overflow
  • CBT: Clear bit
  • SBT: Set bit


Registers

There are 16 registers:
  • 0-3: A0, A1, A2, A3
  • 4-7: X0, X1, X2, X3
  • 8-11: Y0, Y1, Y2, Y3
  • 12-15: P, Z, SP, PC
P is the processor status register.  If used as an index, a constant zero is used instead.  This explains the abs,0 and zp,0 addressing modes in the opcode table above.  They are now indexed modes, but use P as the default index register.  Selection bits in the opcode extension allow other Y0-Y3, Z, SP, or PC to be used instead.  This provides stack- and PC-relative addressing modes for most instructions.

All registers are 32 bits wide.  In most cases, writing to the low 8 or 16 bits will clear the rest of the register.  The exception is writing to the low 8 bits of SP.  For compatibility, this will set the high 24 bits to $000001.

Extension

Most of the new features come through the opcode extension.  There are a few formats for these, depending on the instruction and addressing mode
  • PRRXXXDD
    • Used by most instructions.
    • P selects the alternate operation
    • RR selects the destination register, or a small constant (1-4)
    • XXX selects the index register or source register
    • DD is the operation width. 00 for 8 bit, 01 for 16 bit, 10 for 32 bit, 11 for floating point (where that makes sense)
  • PAAARRRR
    • Used by bit-set and -clear instructions
    • AAA is combined with the base bit from the instruction to form the bit number
    • RRRR is the destination register
  • SSSRRRDD
    • Used by register-move instructions
    • SSS selects the source register
    • RRR selects the destination register
    • DD is the width
  • WNNNVVVV
    • Used by the BRK instruction
    • W enables waiting for an external interrupt
    • NNN selects the external interrupt to wait for
    • VVVV selects the interrupt vector: $0000fffe - 2*VVVV
  • CDILRRRR
    • Used by branch instructions
    • C selects a different set of conditions (BGE, BLT, BLE, BGT, BLS, BHI, BNV, BRA).  BNV is "never", BRA is "always"
    • I enables indirection.  If it is 0, the target address is base register + offset.  If it is 1, then base register + offset points to a memory location containing the target address
    • L enables subroutine calls.  If it is 1, the current PC will be pushed before the branch is taken
    • RRRR is the base register
The register selection fields in opcode extensions don't encode the register number directly.  Instead, each instruction has a default register (to give standard 6502 behavior when the extension is zero).  The register selection field is xored into the lower bits of this register number.

The 6502's flag-clearing and -setting instructions have been generalised to clear or set any bit of any register.  These general instructions as called CBT and SBT.  So CLC is CBT 0, CLI is CBT 2, and so on.  The AAA bits from the extension are shifted up two places, with the lowest bit copied to fill the new ones.  The resulting value is xored into the bit selected by the instruction.  This gives access to all 32 bits.

Similarly, the register-transfer instructions TAX, TYA, and so on, have been generalised to copy any register to any other.  By xoring the instruction's register number with the bits in the extension, all combinations of source and destination register are covered.

Increment, decrement, and the shift/roll instructions have a small constant encoded instead of a destination register.  This makes it possible to add or subtract numbers up to 4 in a single one-byte (16 bit) instruction.  For the acc mode, these instructions use the index register selection to specify the register.

Alternative operations

Many instructions use the 'P' bit in the extension to select a different operation
  • ADC, ACX, ACY -> ADD, ADX, ADY Add without carry
  • SBC, SCX, SCY -> SUB, SBX, SBY Subtract without carry
  • CMP, CPX, CPY -> CPC, CCX, CCY Compare with carry
  • AND, ANX, ANY -> BIC, BCX, BCY Bit clear (dest <- dest and ~source)
  • MUL, DIV, MOD -> MLS, DVS, MDS Signed multiply, divide, mod
  • SQR -> RSQ Reciprocal square root
  • ASL -> ESL Shift left, filling with the right-most bit
  • LSR -> ASR Shift right, filling with the left-most bit
  • ROL , ROR -> RLB, RRB Rotate without carry
  • CBT -> TBT Test bit.  The Z flag is set if the tested bit is zero, cleared if it is one
  • SBT -> XBT Toggle bit

No comments:

Post a Comment