Difference between revisions of "Sweet 16"

From SEGGER Wiki
Jump to: navigation, search
(Created page with "Sweet 16 Some programs have been using Sweet 16, a pseudo processor implemented originally by Steve Wozniak https://en.wikipedia.org/wiki/Steve_Wozniak Sweet 16 was a pseudo...")
 
m
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
Sweet 16
+
[[Category:Knowledge Base]]
  
Some programs have been using Sweet 16, a pseudo processor implemented originally by Steve Wozniak https://en.wikipedia.org/wiki/Steve_Wozniak Sweet 16 was a pseudo 16-bit processor, with 16 16-bit registers. It required 32-bytes in the Zero page of the 6502, to hold the values of these registers and needed less instructions than the 6502 for most programs. Typical programs written in SWEET-16 needed about half the size and 5 to 10 times as much time as pure 6502 assembly code. The Sweet 16 executer was implemented in the ROM of the original Apple ][. 6502 assembler and Sweet 16 could be mixed easily: Sweet 16 code was inlined and simply preceeded by a function call to the executer, which was located at a known address (0xF689 or in Apple speech $F689) could easily be started by a subroutine call. Despite its simplicity, Sweet 16 achieved an amazing code density, which is still hard to beat today. For more information on SWEET-16, see http://www.6502.org/source/interpreters/sweet16.htm
+
SWEET16 is a pseudo processor implemented originally by Steve Wozniak https://en.wikipedia.org/wiki/Steve_Wozniak.
 +
 
 +
SWEET16 code is executed on a pseudo 16-bit CPU with sixteen internal 16-bit registers.
 +
 
 +
== Registers ==
 +
SWEET16 has 16 internal 16-bit registers, named R0 .. R15.
 +
Some registers have well-defined functions:
 +
 
 +
* R0 – [[Accumulator]
 +
* R12 – Stack Pointer
 +
* R13 – stores the result of all comparison operations
 +
* R14 – Status register
 +
* R15 – Program Counter
 +
 
 +
 
 +
It required 32-bytes in the Zero page of the [[6502]], to hold the values of these registers and needed less instructions than the 6502 for most programs. Typical programs written in SWEET-16 needed about half the size and 5 to 10 times as much time as pure 6502 assembly code. The Sweet 16 executer was implemented in the ROM of the original Apple ][. 6502 assembler and Sweet 16 could be mixed easily: Sweet 16 code was inlined and simply preceeded by a function call to the executer, which was located at a known address (0xF689 or in Apple speech $F689) could easily be started by a subroutine call. Despite its simplicity, Sweet 16 achieved an amazing code density, which is still hard to beat today. For more information on SWEET16, see http://www.6502.org/source/interpreters/sweet16.htm
 +
 
 +
== Memory allocation ==
 +
SWEET16 requires storage in the zero page area for the registers. This has to be 32 consecutive bytes. In the original Apple implementation, the first 32 bytes located from $0 -$1F were used,
 +
however, the code can use any other range.
 +
For program space, about 300 bytes are required for the implementation on the 6502. On the 6502, an 8-bit Jumptable was used, which required all relevant code to be located in the same page (meaning
 +
the high byte of the address to be identical)
 +
The code can of course be ported to any other processor or written in C.
 +
 
 +
== Instructions ==
 +
 
 +
Non-register operations
 +
    00        RTN              (Return to Native 6502 mode)
 +
    01        BR        ea    (Branch always)
 +
    02        BNC      ea    (Branch if No Carry)
 +
    03        BC        ea    (Branch if Carry)
 +
    04        BP        ea    (Branch if Plus)
 +
    05        BM        ea    (Branch if Minus)
 +
    06        BZ        ea    (Branch if Zero)
 +
    07        BNZ      ea    (Branch if NonZero)
 +
    08        BM1      ea    (Branch if Minus 1)
 +
    09        BNM1      ea    (Branch if Not Minus 1)
 +
    0A        BK              (Break)
 +
    0B        RS              (Return from Subroutine - Stay in Sweet16 mode
 +
    0C        BS        ea    (Branch to Subroutine)
 +
    0D                        (Unassigned)
 +
    0E                        (Unassigned)
 +
    0F                        (Unassigned)
 +
Register Operations
 +
 
 +
    1n        SET      Rn    Constant  (Set)
 +
    2n        LD        Rn    (Load)
 +
    3n        ST        Rn    (Store)
 +
    4n        LD        @Rn    (Load Indirect)
 +
    5n        ST        @Rn    (Store Indirect)
 +
    6n        LDD      @Rn    (Load Double Indirect)
 +
    7n        STD      @Rn    (Store Double Indirect)
 +
    8n        POP      @Rn    (Pop Indirect)
 +
    9n        STP      @Rn    (Store POP Indirect)
 +
    An        ADD      Rn    (Add)
 +
    Bn        SUB      Rn    (Sub)
 +
    Cn        POPD      @Rn    (Pop Double Indirect)
 +
    Dn        CPR      Rn    (Compare)
 +
    En        INR      Rn    (Increment)
 +
    Fn        DCR      Rn    (Decrement)
 +
 
 +
== Code efficiency ==
 +
Sweet 16 is an impressive example for high code density.
 +
Take the example of a memcpy() routine:
 +
 
 +
                MEMCPY:
 +
0000 41        LOOP      LD  @R1        // a = *r1++
 +
0001 52                  ST  @R2        // *r2++ = a
 +
0002 F3                  DCR R3          // r3--
 +
0003 07 FB                BNZ LOOP        // Loop until done.
 +
0005 00                  RS              // Return
 +
 
 +
6 bytes for a memcpy routine! Try that on modern processors...<br>
 +
And also note that this code would work the same way in a 32-bit or 64-bit environment. It shows that code density of modern RISC CPUs is way behind where it could be.
 +
 
 +
== References ==
 +
https://en.wikipedia.org/wiki/SWEET16

Latest revision as of 20:35, 8 September 2019


SWEET16 is a pseudo processor implemented originally by Steve Wozniak https://en.wikipedia.org/wiki/Steve_Wozniak.

SWEET16 code is executed on a pseudo 16-bit CPU with sixteen internal 16-bit registers.

Registers

SWEET16 has 16 internal 16-bit registers, named R0 .. R15. Some registers have well-defined functions:

  • R0 – [[Accumulator]
  • R12 – Stack Pointer
  • R13 – stores the result of all comparison operations
  • R14 – Status register
  • R15 – Program Counter


It required 32-bytes in the Zero page of the 6502, to hold the values of these registers and needed less instructions than the 6502 for most programs. Typical programs written in SWEET-16 needed about half the size and 5 to 10 times as much time as pure 6502 assembly code. The Sweet 16 executer was implemented in the ROM of the original Apple ][. 6502 assembler and Sweet 16 could be mixed easily: Sweet 16 code was inlined and simply preceeded by a function call to the executer, which was located at a known address (0xF689 or in Apple speech $F689) could easily be started by a subroutine call. Despite its simplicity, Sweet 16 achieved an amazing code density, which is still hard to beat today. For more information on SWEET16, see http://www.6502.org/source/interpreters/sweet16.htm

Memory allocation

SWEET16 requires storage in the zero page area for the registers. This has to be 32 consecutive bytes. In the original Apple implementation, the first 32 bytes located from $0 -$1F were used, however, the code can use any other range. For program space, about 300 bytes are required for the implementation on the 6502. On the 6502, an 8-bit Jumptable was used, which required all relevant code to be located in the same page (meaning the high byte of the address to be identical) The code can of course be ported to any other processor or written in C.

Instructions

Non-register operations

    00        RTN              (Return to Native 6502 mode)
    01        BR        ea     (Branch always)
    02        BNC       ea     (Branch if No Carry)
    03        BC        ea     (Branch if Carry)
    04        BP        ea     (Branch if Plus)
    05        BM        ea     (Branch if Minus)
    06        BZ        ea     (Branch if Zero)
    07        BNZ       ea     (Branch if NonZero)
    08        BM1       ea     (Branch if Minus 1)
    09        BNM1      ea     (Branch if Not Minus 1)
    0A        BK               (Break)
    0B        RS               (Return from Subroutine - Stay in Sweet16 mode
    0C        BS        ea     (Branch to Subroutine)
    0D                         (Unassigned)
    0E                         (Unassigned)
    0F                         (Unassigned)

Register Operations

    1n        SET       Rn     Constant  (Set)
    2n        LD        Rn     (Load)
    3n        ST        Rn     (Store)
    4n        LD        @Rn    (Load Indirect)
    5n        ST        @Rn    (Store Indirect)
    6n        LDD       @Rn    (Load Double Indirect)
    7n        STD       @Rn    (Store Double Indirect)
    8n        POP       @Rn    (Pop Indirect)
    9n        STP       @Rn    (Store POP Indirect)
    An        ADD       Rn     (Add)
    Bn        SUB       Rn     (Sub)
    Cn        POPD      @Rn    (Pop Double Indirect)
    Dn        CPR       Rn     (Compare)
    En        INR       Rn     (Increment)
    Fn        DCR       Rn     (Decrement)

Code efficiency

Sweet 16 is an impressive example for high code density. Take the example of a memcpy() routine:

               MEMCPY:
0000 41         LOOP      LD  @R1         // a = *r1++
0001 52                   ST  @R2         // *r2++ = a
0002 F3                   DCR R3          // r3--
0003 07 FB                BNZ LOOP        // Loop until done.
0005 00                   RS              // Return

6 bytes for a memcpy routine! Try that on modern processors...
And also note that this code would work the same way in a 32-bit or 64-bit environment. It shows that code density of modern RISC CPUs is way behind where it could be.

References

https://en.wikipedia.org/wiki/SWEET16