6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 20, 2024 4:53 am

All times are UTC




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Mon Sep 01, 2014 4:51 am 
Offline

Joined: Wed Jun 26, 2013 9:06 pm
Posts: 56
This past week I've been thinking a lot about designing my own CPU. I've been testing out things like 2 operand mem-reg instructions and 3 operand reg-reg instructions to see what I like best, and it occurred to me that registers are very confusing to keep tracked of. With the 65816, I've gotten used to giving every memory address a label name, so it is easy to keep track. If memory address can be labeled, could registers be labeled too?


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 5:10 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1922
Location: Sacramento, CA, USA
Even a relatively simple assembler should be able to equate a label with a register name, but it would still be a bit confusing in a large or complex program, because there would be an almost certain need for overlapping labels.

Here is a short SWEET-16 example, using San Bergmans' assembler. Note the register equates starting around line #40:
Code:
0000-                 5 ;-----------------------------------------------------;
0000-                 6 ; BEER SONG FOR THE SWEET16 PSEUDO-PROCESSOR          ;
0000-                 7 ;    BY BARRYM 2011-05-21                             ;
0000-                 8 ;-----------------------------------------------------;
0000-                 9 ; THANKS TO SBPROJECTS.COM FOR LOTS OF VALUABLE INFO  ;
0000-                10 ;    AND A VERY NICE ASSEMBLER!!                      ;
0000-                11 ; THE SWEET16 PROCESSOR WAS CREATED BY STEVE WOZNIAK  ;
0000-                12 ;    IN 1977 TO HELP HIM WRITE COMPACT (BUT SLOWER)   ;
0000-                13 ;    16-BIT CODE ON HIS NEW BABY, THE APPLE II.  HE   ;
0000-                14 ;    NEVER BUILT IT IN HARDWARE, BUT INSTEAD CREATED  ;
0000-                15 ;    A NIFTY LITTLE 372-BYTE INTERPRETER AND BURNED   ;
0000-                16 ;    IT INTO THE ROM OF THE ORIGINAL INTEGER BASIC    ;
0000-                17 ;    APPLE II.                                        ;
0000-                18 ; SWEET16 CODE AND 6502 CODE CAN CO-EXIST PEACEFULLY  ;
0000-                19 ;    IN AN APPLE II MACHINE LANGUAGE PROGRAM; A 6502  ;
0000-                20 ;    'JSR $F689' IMMEDIATELY PRECEDES A BLOCK OF IN-  ;
0000-                21 ;    LINE SWEET16 INSTRUCTIONS AND A SWEET16 'RTN'    ;
0000-                22 ;    SWITCHES BACK TO 6502 MODE, WHICH MUST BE DONE   ;
0000-                23 ;    AT OR BEFORE PROGRAM COMPLETION.  THE ORIGINAL   ;
0000-                24 ;    APPLE II HAD AN UPPER-CASE 40-COLUMN DISPLAY AS  ;
0000-                25 ;    STANDARD EQUIPMENT, SO THE OFFICIAL SONG LYRICS  ;
0000-                26 ;    ARE ADJUSTED ACCORDINGLY.                        ;
0000-                27 ; NOTE:  'ADD' AND 'SUB' ARE BUILT-IN 6502 MACROS IN  ;
0000-                28 ;    THE CURRENT VERSION OF THIS ASSEMBLER AND WILL   ;
0000-                29 ;    NOT ASSEMBLE TO THE CORRECT SWEET16 OPCODES (USE ;
0000-                30 ;    '.DA #$AX' FOR 'ADD X' & '.DA #$BX' FOR 'SUB X') ;
0000-                31 ;-----------------------------------------------------;
0000-                32 ; CONSTANT EQUATES                                    ;
0000-                33 ;-----------------------------------------------------;
F689-                34 SWEET16  =   $F689      ROM: WOZ' INTERPRETER
E51B-                35 BIN2ASC  =   $E51B      ROM: PRINT UNSIGNED16
FDED-                36 PUTCHAR  =   $FDED      ROM: PRINT CHARACTER
0063-                37 MAXB     =   99         MUST BE IN [1..65535]
0000-                38 ;-----------------------------------------------------;
0000-                39 ; REGISTER EQUATES                                    ;
0000-                40 ;-----------------------------------------------------;
0000-                41 ACC      =   $0         SWEET16 MAIN ACCUMULATOR
0001-                42 BEER     =   $1         BEER COUNTER
0002-                43 TYPE     =   $2         SUBPHRASE TYPE TEMP
0003-                44 PTR      =   $3         TEXT POINTER
000C-                45 STK      =   $C         SWEET16 STACK POINTER
0000-                46 ;-----------------------------------------------------;
0000-                47 ; MAIN PROGRAM                                        ;
0000-                48 ;-----------------------------------------------------;
0E00-                49         .OR  $0E00
0E00-20 89 F6        50 MAIN    JSR  SWEET16    ENTER SWEET16 MODE
0E03-1C 00 01        51         SET  STK,$0100  INIT SWEET16 STACK POINTER
0E06-11 63 00        52         SET  BEER,MAXB  BEER = MAXB
0E09-B0              53         .DA  #$B0       'SUB ACC' (TYPE=0)
0E0A-0C 07           54         BS   PRSONG     PRINT THE ENTIRE SONG
0E0C-00              55         RTN             RETURN TO 6502 MODE
0E0D-60              56         RTS             EXIT
0E0E-                57 ;-----------------------------------------------------;
0E0E-                58 ; PRINT ALL EXCEPT THE LAST SENTENCE                  ;
0E0E-                59 ;-----------------------------------------------------;
0E0E-13 5C 0E        60 BEERME  SET  PTR,TAKE   EMIT "TAKE ONE ... IT AROUND,"
0E11-0C 12           61         BS   PRBOB      EMIT " ... ON THE WALL."
0E13-13 7D 0E        62 PRSONG  SET  PTR,CR     EMIT BLANK LINE
0E16-0C 0D           63         BS   PRBOB      EMIT " ... ON THE WALL";
0E18-F0              64         DCR  ACC        TYPE = -1
0E19-13 7C 0E        65         SET  PTR,COMCR  EMIT ","
0E1C-0C 07           66         BS   PRBOB      EMIT " ... OF BEER."
0E1E-E0              67         INR  ACC        TYPE = +1
0E1F-F1              68         DCR  BEER       BEER = BEER - 1
0E20-09 EC           69         BNM1 BEERME     IF BEER <> -1 THEN BEERME
0E22-                70 ;-----------------------------------------------------;
0E22-                71 ; SET UP LAST SENTENCE AND FALL THRU                  ;
0E22-                72 ;-----------------------------------------------------;
0E22-11 63 00        73         SET  BEER,MAXB  BEER = MAXB
0E25-                74 ;                       EMIT "GO TO ... BUY SOME MORE,"
0E25-                75 ;-----------------------------------------------------;
0E25-                76 ; PRINT A PROPERLY PUNCTUATED BOTTLE SUB-PHRASE       ;
0E25-                77 ; (ENTRY): PTR CONTAINS PRE-STRING POINTER, ACC       ;
0E25-                78 ;    CONTAINS SUB-PHRASE TYPE (0 = " ... THE WALL",   ;
0E25-                79 ;    -1 = " ... OF BEER.", +1 = " ... THE WALL.")     ;
0E25-                80 ; (EXIT):  ACC IS CLEARED                             ;
0E25-                81 ;-----------------------------------------------------;
0E25-32              82 PRBOB   ST   TYPE
0E26-0C 25           83         BS   PUTS       EMIT PRE-STRING
0E28-21              84         LD   BEER       IF BEER = 0 THEN
0E29-06 0E           85         BZ   PRBOTT        EMIT "NO MORE";
0E2B-00              86         RTN             IF BEER > 0 THEN
0E2C-A5 03           87         LDA  $03           RETURN TO 6502 MODE JUST
0E2E-A6 02           88         LDX  $02           LONG ENOUGH TO CONVERT AND
0E30-20 1B E5        89         JSR  BIN2ASC       EMIT BEER TO ACTIVE OUTPUT
0E33-20 8C F6        90         JSR  SWEET16+3
0E36-13 86 0E        91         SET  PTR,BOTTL
0E39-0C 12           92 PRBOTT  BS   PUTS       EMIT " ... BOTTLE";
0E3B-F1              93         DCR  BEER
0E3C-07 01           94         BNZ  NEQ1       IF BEER = 1 THEN
0E3E-E3              95         INR  PTR           SKIP OVER THE "S"
0E3F-E1              96 NEQ1    INR  BEER
0E40-0C 0B           97         BS   PUTS       EMIT " ... OF BEER";
0E42-22              98         LD   TYPE
0E43-08 05           99         BM1  NOWALL     IF TYPE >= 0 THEN
0E45-0C 06          100         BS   PUTS          EMIT " ON THE WALL";
0E47-22             101         LD   TYPE
0E48-06 11          102         BZ   KPUT       IF TYPE <> 0 THEN
0E4A-13 A5 0E       103 NOWALL  SET  PTR,DOTCR     EMIT "."
0E4D-               104 ;-----------------------------------------------------;
0E4D-               105 ; PRINT A NULL-TERMINATED STRING @ PTR                ;
0E4D-               106 ; (ENTRY): PTR POINTS TO THE START OF THE STRING      ;
0E4D-               107 ; (EXIT):  PTR POINTS TO THE NEXT STRING IN MEMORY,   ;
0E4D-               108 ;          ACC IS CLEARED                             ;
0E4D-               109 ;-----------------------------------------------------;
0E4D-43             110 PUTS    LD   @PTR       GRAB CHAR @ PTR AND ADVANCE PTR
0E4E-06 0B          111         BZ   KPUT       IF CHAR <> NULL THEN
0E50-00             112         RTN                ESC TO 6502 MODE
0E51-A5 00          113         LDA  $00           JUST LONG ENOUGH TO EMIT
0E53-20 ED FD       114         JSR  PUTCHAR       THE CHAR TO ACTIVE OUTPUT
0E56-20 8C F6       115         JSR  SWEET16+3
0E59-01 F2          116         BR   PUTS       LOOP UNTIL NULL
0E5B-0B             117 KPUT    RS              RETURN
0E5C-               118 ;-----------------------------------------------------;
0E5C-               119 ; OPTIMIZED SONG LYRIC STRING                         ;
0E5C-               120 ;-----------------------------------------------------;
0E5C-D4 C1 CB C5
0E60-A0 CF CE C5
0E64-A0 C4 CF D7
0E68-CE A0 C1 CE
0E6C-C4 A0 D0 C1
0E70-D3 D3 A0 C9
0E74-D4 A0 C1 D2
0E78-CF D5 CE C4    121 TAKE    .AS  -"TAKE ONE DOWN AND PASS IT AROUND"
0E7C-AC             122 COMCR   .AS  -","
0E7D-8D 00          123 CR      .AZ  -#13
0E7F-CE CF A0 CD
0E83-CF D2 C5       124         .AS  -"NO MORE"
0E86-A0 C2 CF D4
0E8A-D4 CC C5 00    125 BOTTL   .AZ  -" BOTTLE"
0E8E-D3 A0 CF C6
0E92-A0 C2 C5 C5
0E96-D2 00          126         .AZ  -"S OF BEER"
0E98-A0 CF CE A0
0E9C-D4 C8 C5 A0
0EA0-D7 C1 CC CC
0EA4-00             127         .AZ  -" ON THE WALL"
0EA5-AE 8D 00       128 DOTCR   .AZ  -".",#13
0EA8-C7 CF A0 D4
0EAC-CF A0 D4 C8
0EB0-C5 A0 D3 D4
0EB4-CF D2 C5 A0
0EB8-C1 CE C4 A0
0EBC-C2 D5 D9 A0
0EC0-D3 CF CD C5
0EC4-A0 CD CF D2
0EC8-C5 AC 8D 00    129         .AZ  -"GO TO THE STORE AND BUY SOME MORE,",#13
0ECC-               130         .EN


Mike


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 7:37 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8138
Location: Midwestern USA
Aaendi wrote:
This past week I've been thinking a lot about designing my own CPU. I've been testing out things like 2 operand mem-reg instructions and 3 operand reg-reg instructions to see what I like best, and it occurred to me that registers are very confusing to keep tracked of. With the 65816, I've gotten used to giving every memory address a label name, so it is easy to keep track. If memory address can be labeled, could registers be labeled too?

Depends on context. Are you talking about VHDL, assembly language, or what?

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 9:24 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
For assembly: if any opcode mnemonic includes a reference to the register (INX, DEY, PHA) the answer is no. If registers are only referred to by operands, the answer is yes. For example the AVR assembler has a .DEF statement (.DEF myregister = r21).

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 6:11 pm 
Offline

Joined: Mon Aug 05, 2013 10:43 pm
Posts: 258
Location: Southampton, UK
The question could become: are registers an optimisation (or a technical compromise, if you prefer to look at it like that) or do they add instead make possible things which would be imossible without them?

I suspect the answer is the former. Ie they simplify the design and act as a sort of cache, albeit one managed by the programmer.

I'd be very surprised if there aren't real CPUs available which have no registers. But I doubt they'd have gained much real-world traction, because in the real-world optimisations (for example, against runtime speed) are important.

_________________
8 bit fun and games: https://www.aslak.net/


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 6:54 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1922
Location: Sacramento, CA, USA
It's difficult for me to imagine an architecture that doesn't have at least an accumulator, instruction pointer, memory access register and memory data register, but I am willing to bet that it's possible to construct a stored-program, Turing-complete machine with less. It really boils down to whether or not a programmer is comfortable with its assembly language, and whether or not it has adequate performance for the job at hand.

CPU architectures that are not human-friendly may be compiler-friendly, or vice-versa. The favorites are usually both. I have the most fun and highest comfort-level with four to eight GP registers, but I may be in the minority here.

Mike


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 6:57 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 387
Location: Minnesota
I suppose it would be possible create a processor whose every instruction referenced memory. So:

Code:
  mov absolute0,#mylabel
  mov absolute1,#1000
loop:
  mov (absolute0),#$00
  inc absolute0
  dec absolute1
  bne absolute1,loop
  rts 


But even if there are no programmer-available register, the processor will almost certainly need some "hidden" internal registers to handle addressing, arithmetic and logic operations. The operands still have to be fetched from memory, operated on, and stored back, even if the process is invisible to the user.


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 7:17 pm 
Offline
User avatar

Joined: Wed Aug 27, 2014 6:05 pm
Posts: 6
Complete and useful CPUs can work without registers as part of the machine instructions. Once instance is the Zylin CPU core, which is a tiny 32-bit processor designed to be synthesized into FPGAs with complete support by the GCC compiler. It's stack based.

A nice overview is given here: http://retroramblings.net/?p=434


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 8:31 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
kiamnetrem wrote:
Complete and useful CPUs can work without registers as part of the machine instructions. Once instance is the Zylin CPU core, which is a tiny 32-bit processor designed to be synthesized into FPGAs with complete support by the GCC compiler. It's stack based...

But does this make code easier to write?

Personally, I always felt limited by the 6502's X and Y registers and one accumulator. All the TYA, PLA, PHX's etc., while not a pain to follow in code, does take away from the overall machine code's speed. More registers would seem that less of the stack would be used...

One thing lacking in the 65Or16 that I would have liked for my 'take' on a better 6502, i.e. 65Org16, would have been simple SWAP opcodes to accomodate the 16 accumulators and x,y,w registers. But it does have the ability to transfer a value from any of the 16 accumulators/3 registers amongst themselves. Obviously this is not a SWAP though.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 9:11 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8424
Location: Southern California
ElEctric_EyE wrote:
kiamnetrem wrote:
Complete and useful CPUs can work without registers as part of the machine instructions. Once instance is the Zylin CPU core, which is a tiny 32-bit processor designed to be synthesized into FPGAs with complete support by the GCC compiler. It's stack based...

But does this make code easier to write?

I haven't looked into that particular one, but a stack processor's native language is basically Forth, ie, that it takes very little processing for a compiler to turn Forth into the machine language; so I would venture to say that yes, it's easier to write. These are incredible performers considering their hardware simplicity and clock speeds. The stacks are onboard though, each with its own bus, so they don't have to go out on the normal memory bus for stack access, and accesses can be done on multiple buses at the same time.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 9:30 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
GARTHWILSON wrote:
... a stack processor's native language is basically Forth, ie, that it takes very little processing for a compiler to turn Forth into the machine language; so I would venture to say that yes, it's easier to write. These are incredible performers considering their hardware simplicity and clock speeds. The stacks are onboard though, each with its own bus, so they don't have to go out on the normal memory bus for stack access, and accesses can be done on multiple buses at the same time.

Multiple stacks better than more registers? Is this because of the single cycle push/pull opcodes or the compiler?
Forgive me, I've been away from 6502 (even 65Org16) software for a few months.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 9:36 pm 
Offline

Joined: Wed Jun 26, 2013 9:06 pm
Posts: 56
I just tried coding psuedo-assembly for a CPU with 4 general purpose registers (A, B, X and Y), ARM-style shifting, and 6809-style mnemonics and so far it looks like I would be comfortable programming it.

Code:
ldy   {x_pixel},(x)
lda   y >> 4
anda   #$001f
ldb   {y_pixel},(x)
andb   #$01f0
ora   b << 1
andy   #$fe00
ora   y << 1
lda   {bg_map},(a)
anda   #$03ff
lda   {collision_data},(a)


This code is supposed to check what BG tile a pixel overlaps. It seems like enough general purpose registers to make it easier than the 65xx, but not enough to be difficult to keep track of.


Last edited by Aaendi on Tue Sep 02, 2014 11:42 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 01, 2014 11:55 pm 
Offline
User avatar

Joined: Sun Dec 29, 2002 8:56 pm
Posts: 449
Location: Canada
Having more registers available (to a point) makes it easier to get performance from a high-level compiled language like C or C++.
It's been studied, registers vs stack vs accumulator architectures.
They added more regs (r8-r15) to the x86 arch. to improve performance for some software.

Depending on what the target application of the processor is one may want more or fewer registers.
The 6502 works great with just .A, .X. and .Y for 6502 style apps.

If one isn't planning on using a high-level language compiler then it may not make that much difference how many registers are available. I wrote most of a bootrom in assembler using only four registers. Even though more registers were available it would make little difference to performance.
I use 256 regs for my latest cpu; but I intend on using compiled languages with it.
64 bit cpu's seem to have more regs. (IA64, MMIX, ).

So the answer is: I don't think registers make code easier to write; they can just enhance performance sometimes.

_________________
http://www.finitron.ca


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 02, 2014 5:06 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8424
Location: Southern California
ElEctric_EyE wrote:
GARTHWILSON wrote:
... a stack processor's native language is basically Forth, ie, that it takes very little processing for a compiler to turn Forth into the machine language; so I would venture to say that yes, it's easier to write. These are incredible performers considering their hardware simplicity and clock speeds. The stacks are onboard though, each with its own bus, so they don't have to go out on the normal memory bus for stack access, and accesses can be done on multiple buses at the same time.

Multiple stacks better than more registers? Is this because of the single cycle push/pull opcodes or the compiler?

If they're onboard and have their own buses, imagine doing an operation on a number from one of the stacks and putting the result on the other stack while at the same time fetching the next instruction, all in the same cycle. A few instructions can even be combined--by the compiler I assume--such that the Harris RTX2000 routinely did 16 Forth MIPS at 12MHz. Doing 16 Forth MIPS on a 6502 in ITC Forth would require about 1.25GHz, and the '816 would require about 500MHz.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 02, 2014 8:10 am 
Offline

Joined: Fri Nov 09, 2012 6:52 am
Posts: 16
I use a macro that I named 'mb' (Move Byte). It can output the correct code to move a byte from one location to to another:

Code:
; move from one memory location to another, use A by default:
mb foo := bar
; move using .X:
mb x, foo := bar


You can probably guess why code is output. Also, it can handle:
Code:
mb a := bar ; will output 'lda bar'
mb foo := a ; 'sta foo'


In which case you could name register A and have it be useful:
Code:
; ca65 .define macro:
.define baz a
mb baz := bar ; will output 'lda bar'
mb foo := baz ; 'sta foo'


But for standard 6502, I don't think naming registers can really help much.
You might be able to:
Code:
.define offset x
ldx index
lda table, offset

But that might be pretty confusing over a comment.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: