Searching \ for '17C5X' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=17c5x
Search entire site for: '17C5X'.

Truncated match.
PICList Thread
'17C5X'
1997\05\23@221613 by Andres Djordjalian

flavicon
face
Hi John!

> While there are certainly exceptions to any rule, most programs that need
> a lot of RAM need it for arrays or other such constructs.  Given that any
> array access has some associated setup work anyhow, having to deal with

I agree, but those constructs can be plenty and small, instead of one
or two big ones.

> array banks isn't a big deal.  For simple variables, however, it's nice to
> simply *ignore* bank-switching and related concepts.  If 96 bytes' worth
> of registers are non-banked, then the vast majority of applications--even
> those which use up hundreds of bytes worth of arrays--will be able to
> handle all their non-array needs without bank-switching.

I was thinking of the following. Lets say you have a set of routines that
handle some sort of calculations that use an array. Would you put the
array and the other variables in the same page or not? You don't want to
limit its use to a single project, maybe you'll first use it in a small
program but later reuse it for a large one. If you switched banks the
first time it would be a waste of code and efficency, if you modified it
for the second program you would be forced to play with code you've
programmed some time ago, and if you consider both options from a start
you would have to work more.

I'd rather try to use not more than one bank for a component's
variables, minimizing bank-switching inside the component, and leave the
bank-switching for the interface between them. I find it easier to
plan a efficent organization if you work that way. And if RAM pages are
large this is easier to do. I don't mean to say that 224 vs. 128 bytes is
very much important, but, on the other side, would it be that handy to
have a large common area?

> Further, even for programs that do need large arrays [bigger than 128
> bytes] the overhead of selecting the appropriate 128-byte page is really
> not severe.  In fact, with arrays that span pages it's probably easier to
> deal with 128-byte pages (power of two) than 224-byte pages (not a power
> of two).  For example, suppose ArrayH:ArrayL is a two-byte pointer to a
> ...............

Ok, I'll put that on the scale too, but I still think the best choice is
not clear. I mean, how many times will you need an array that takes almost
all of the memory, not being able to spare ten or so extra machine-cycles
to access it, nor program it's client in such a way as to use a pair of
bank and offset pointers? Can't think of many, but I can think of a lot of
times when I'll be organizing a program working much more comfortably
because I have larger pages.

> I agree that a "nice" implementation (like a BANKFSR register) would
> probably have added a little silicon; IMHO the benefits from being able to
> truly bank the IND's would probably be worth it.  Certainly, though,
> while we can debate about the exact best size for the banked/unbanked
> split I hope you will agree with me that there oughta be more than SIX
> unbanked registers?

I may be, as I told you I haven't programmed the 17CXX family and I've
no experience on unbanked regs. But yeah, it sounds as if six were too
few, perhaps they could have added another bit and put sixteen more, but
before criticizing this I'd like to see more clearly what the real
drawbacks of scarce unbanked regs are.

> ...
> those which improve programmer convenience without much cost whatsoever.
> I think placing the bank split in a better place would have fallen in the
> latter category.  My choice of 128 was intended both as a compromise
> ....

I agree, I'm just not sure if having many more unbanked regs results in
improved programmer convenience.

Regards,

Andres Djordjalian
spam_OUTadjordjTakeThisOuTspamaleph.fi.uba.ar

1997\05\24@141211 by John Payson

flavicon
face
> Hi John!

Hello.

> > While there are certainly exceptions to any rule, most programs that need
> > a lot of RAM need it for arrays or other such constructs.  Given that any
> > array access has some associated setup work anyhow, having to deal with
>
> I agree, but those constructs can be plenty and small, instead of one
> or two big ones.

Right, but see below...

{Quote hidden}

I might but them all in the same page, but I'd prefer to put the
simple-variables in a non-banked section and the array itself in a banked
section.  This would allow the routine to use any of several arrays, in
different banks, without any changes to the code itself [assuming the
routine's caller set the appropriate array bank].

>                                                         You don't want to
> limit its use to a single project, maybe you'll first use it in a small
> program but later reuse it for a large one. If you switched banks the
> first time it would be a waste of code and efficency, if you modified it
> for the second program you would be forced to play with code you've
> programmed some time ago, and if you consider both options from a start
> you would have to work more.

What is wrong with simply saying that whoever calls the routine should set
the bank-switch register to the appropriate bank?  If there is only one
bank that's used for the array, that setting can simply be done at the
start of the program.  Otherwise, it can be done just before the routine.

Admittedly, if a routine uses TWO arrays which may be in different banks
then things get much more complicated.  Here too, though, unless the CPU
is nice enough to allow independent banking of the two FSR's (which IMHO
the 17Cxx oughta be but isn't) your best bet will frequently be to put one
of the arrays in non-banked space and one in banked space, or else to copy
part [or all] of one array into non-banked space and then switch to the
other array's bank.  Both of these approaches can be practical and
efficient if the non-banked area is large, but are quite impossible if the
non-banked region is only 6 bytes.

> I'd rather try to use not more than one bank for a component's
> variables, minimizing bank-switching inside the component, and leave the
> bank-switching for the interface between them. I find it easier to
> plan a efficent organization if you work that way. And if RAM pages are
> large this is easier to do. I don't mean to say that 224 vs. 128 bytes is
> very much important, but, on the other side, would it be that handy to
> have a large common area?

If the common area is 96 bytes, then it's extremely likely that most or
all of a program's non-array variables will be accessible *ALL THE TIME*
without *ANY* bank switching.  While there are certainly exceptions to
this rule, it does seem to hold pretty well.

Are you at all familiar with the 8x51 architecture?  On that machine,
there are three primary ways to access memory:

 Direct data: 128 bytes which can be accessed directly.  Since
   addresses below 32 are usually reserved, this leaves 96 bytes.  [note:
   a few CPU's in the family only implement the first 64 bytes of this]

 Indirect data: 256 bytes, the first 128 of which overlap direct data.
   These locations are harder to access (you must set up the "FSR" equiv-
   alent and use the "IND" equivalent) but are still on-chip. [note: some
   CPU's in the family only implement the first 64 or 128 bytes of this]

 External memory: 64K of address space entirely independent of the inter-
   nal 256 bytes; these locations are a pain in the tusch to access.
   Pretty much equivalent to the external memory on the 17Cxx.

While I've done some '5x jobs which have needed more than 128 bytes of
memory, I've never done one which needed more than the 96/128 bytes of
direct data for non-array objects (since arrays have to be accessed
indirectly anyhow, placing them in IDATA doesn't cost anything more).
While I don't doubt that some jobs would require more than 96 bytes direct
storage, I expect that some of that memory would be seldom-accessed and
could be placed in an upper bank without significant loss of efficiency.

{Quote hidden}

Perhaps you can think of oodles of applications which would particularly
benefit from having arrays between 128 and 224 bytes in size.  I for one
can think of many more applications that would benefit from the larger
common area.

{Quote hidden}

Okay, for starters...

[1] If unbanked registers are at least moderately plentiful, then many
   interrupt service routines will be able to complete fully without
   having to bank-switch at all.  This would save three cycles on every
   single interrupt service event.

[2] If unbanked registers are scarce, then it becomes difficult to pass
   information among different modules.  Suppose, for example, I have a
   procedure FOO which needs to call procedure BAR, giving it four bytes
   of parameters, and BAR then needs to call procedure BOZ.  All three of
   these routines happen to have their variables in different banks.

   If unbanked memory were plentiful, then all the parameter passing
   could be done in unbanked memory (in fact, probably ALL of the simple
   variables used by the different routines would be in unbanked memory).
   But with unbanked memory scarce I'd have to have the first routine put
   the parameters into unbanked memory, then call the second routine
   which would have to COPY THEM OUT, then put its parameters to the
   third routine in unbanked memory, etc.  Much less efficient than if
   unbanked memory is plentiful.

> > those which improve programmer convenience without much cost whatsoever.
> > I think placing the bank split in a better place would have fallen in the
> > latter category.  My choice of 128 was intended both as a compromise
> > ....
>
> I agree, I'm just not sure if having many more unbanked regs results in
> improved programmer convenience.

It results in a tremendous improvement in programmer convenience because
it means that you don't need to worry about banking for 90% of your
variables [most programs use lots of small variables and a few big ones.
If unbanked memory is reasonably plentiful, then only the [few] big ones
will need to be banked.

Personally, what I really would have liked to have seen would be something
more or less akin to the 8x51, but with some enhancements [far too late
now, though]

DIRECT MODE ACCESS:

Addresses 00-0F: Special-purpose registers, much as they are now, but with
 the timer stuff removed to make way for a new bank-switch register,
 and possibly PRODL and PRODH.  To simplify the architecture, I'd also
 probably make WREG read-only and re-add the movf instruction.

Addresses 10-17: General-purpose RAM (possibly with PRODL/PRODH at 10-11),
 accessible via movpf/movfp

Addresses 18-3F: General-purpose unbanked RAM

Addresses 40-7F: Eight banks of eight I/O registers.  The movpf/movfp
 instructions would be bank-switched to select a group of eight, but
 other instructions could access any register directly.

Address 80-FF: Bank-selected memory, using bits 3-7 of the BSR.

INDIRECT MODE ACCESS via FSR0

Address 00-FF: Bank-selected memory, using bits 0-3 of IBSR

INDIRECT MODE ACCESS via FSR1

Address 00-FF: Bank-selected memory, using bits 4-7 of IBSR


This architecture would allow indirectly-accessed memory [arrays and such]
to be accessed cleanly in banks of 256 addresses, while allowing any
indirectly-accessible location to also be accessed directly.  For
applications that did not require direct access to all memory, a full 168
bytes of "non-banked" direct-addressed storage would be available.

Oh well, too late now...

1997\05\25@224057 by Andres Djordjalian

flavicon
face
John:

> IF you are using c language and also dividing up the code into in-line and
> realtime parts as in New Micros' (http://www.newmicros.com/isomax.html )
> approach, and reusing code, then you would want to make a routine for
> starting to execute at a new bank address after one of your real time waits
> is done and you have a little in-line code to do to get to the next wait.
> in that case, the banks having only a few SFR's related to them is not a
> problem since you save the state  of your program every time you get to a
> wait state in it. (You save the program state in regular memory somewhere).
> If you make a routine or a "word" in your language for going to a new
> memory bank, it's not a big deal.
> One way to do it is with a virtual machine approach using CFLEA
> (http://www.dunfield.com/catalog.html#cflea) by dunfield.
> A value added reseller of DDS's CFLEA is
> (http://www.sistudio.com/)   although, the fact that they resell and add
> onto CFLEA is not on the web site right now..?!...  If interested, give
> them a word or two at .....infoKILLspamspam@spam@sistudio.com
> John Griessen

I'm not sure of fully understanding what you wrote here, if you have more
information on the isostructure approach (other than the given in the URL
you mention) in electronic format I'd appreciate you sent it to me, but it
sounds as you're suggesting ways of solving our dilemmas in run-time. I'm
sure we can do that in many ways but what we were looking for (or at least
I was) is a simple way of doing things efficently, cause the thread
started with a small difference of opinions regarding the architecture of
these micros. I believe any architecture could be made to do anything with
a virtual machine given enough resources, but the point here is to know
which one gives more facilities to implement most solutions, including the
virtual machine.

Nevertheless, thanks for informing me about isostructure programming, I'd
like to know more about that.

Regards,

Andres Djordjalian
adjordjspamKILLspamaleph.fi.uba.ar

1997\05\25@224303 by Andres Djordjalian

flavicon
face
John:

> > I was thinking of the following. Lets say you have a set of routines that
> > handle some sort of calculations that use an array. Would you put the
> > array and the other variables in the same page or not?
> I might but them all in the same page, but I'd prefer to put the
> simple-variables in a non-banked section and the array itself in a banked
> section.  This would allow the routine to use any of several arrays, in
> different banks, without any changes to the code itself [assuming the
> routine's caller set the appropriate array bank].

That could be handy but you could also do it in other ways, and perhaps
better cause if you do it using different banks you would be forced to
use the same addresses and that could get complicated if you have many
arrays. I don't see it as a powerful argument.

{Quote hidden}

Let me put clear what the process I'm calling "organizing a program" would
be on a 17CXX.

First you would program the components you need (interfaces, parsers,
buffers, etc.) When you do so you'd use the same bank for each component
(with the exceptions you might be thinking of.)

Later on, separately, you would want to assemble a system. The first thing
to do is try to compile the whole thing using only one bank. If if fits,
great, but if it doesn't then you would have to decide which bank to use
for each component. To do so, it would be handy to make a diagram of
the relations between components and, having in consideration the RAM
usage of each, "cut" the diagram into two zones of low cohesion. Then, by
hand, arrange the bank switching you need for the interface between these
two parts, which is not very much work cause you cared to find a low
cohesion interface to do the cut. Finish by adding the three lines for
saving the current bank in your interrupt routine. In my opinion, doing
all this is not much work and it's fairly efficent as bank switching would
only be done for a seldom used interface, but it wouldn't be that easy and
efficent if pages were smaller.

Now, lets consider a C compiler (or any other algol-like) that used a
stack for variables and interfaces. It would be much more practical to
have a large page for the stack. If the stack needed more RAM it could use
more banks and the compiler would handle bank-switching at run-time, at
the expense of speed. The programmer could have the option of using a
small fast stack or a big slower one.

This is the process I'm thinking of, it results in not much work, little
bank switching, good reusability, efficency for all cases (including those
when one page is enough), and you don't have to count on having all the
simple variables fitting in a given number of registers. If pages got
smaller all this would be less practical, and I'm not sure of being able
to get all the advantages you've been talking of as often as needed to
compensate for it. That's what I was talking about on my last posting.

> ......
> the 17Cxx oughta be but isn't) your best bet will frequently be to put one
> of the arrays in non-banked space and one in banked space, or else to copy
> part [or all] of one array into non-banked space and then switch to the
> other array's bank.  Both of these approaches can be practical and
> efficient if the non-banked area is large, but are quite impossible if the
> non-banked region is only 6 bytes.

Can't you just change banks while processing the arrays? Don't forget
about the MOVLB instruction.

> While I've done some '5x jobs which have needed more than 128 bytes of
> memory, I've never done one which needed more than the 96/128 bytes of
> direct data for non-array objects (since arrays have to be accessed
> indirectly anyhow, placing them in IDATA doesn't cost anything more).
> While I don't doubt that some jobs would require more than 96 bytes direct
> storage, I expect that some of that memory would be seldom-accessed and
> could be placed in an upper bank without significant loss of efficiency.

You're counting on that and I don't see a reason. I wrote a program for a
16C73 that uses about 90 registers for non-array variables, even though
I'm overlapping them I believe as much as they can. If I had four times
the ROM I could improve that system a lot and I'd surely exceed 96
registers.

> > before criticizing this I'd like to see more clearly what the real
> > drawbacks of scarce unbanked regs are.
> Okay, for starters...
> [1] If unbanked registers are at least moderately plentiful, then many
>     interrupt service routines will be able to complete fully without
>     having to bank-switch at all.  This would save three cycles on every
>     single interrupt service event.

Well, yes, I've put that on the scale already but I don't find it heavy at
all. You're talking about only three cycles!

{Quote hidden}

I think this argument is more powerful, but you would do this only to
skip a step in the process of organizing a program and if you wanted to
write code that needs no changes at all when reused. That sounds ok, but
on the other hand the step and the changes that would be necessary with
the process I just described are a few and easy to do, and with your
scheme, if 96 registers were not enough, you would still have
unbanked-interface and banked-regular variables for every component and I
find that hard to work with, specially considering that while programming
the routines you don't know yet if the whole will fit or not in one page.
I believe you won't be getting a result as efficent as with the other
process. Perhaps I am overlooking something. . .

> It results in a tremendous improvement in programmer convenience because
> it means that you don't need to worry about banking for 90% of your
> variables [most programs use lots of small variables and a few big ones.
> If unbanked memory is reasonably plentiful, then only the [few] big ones
> will need to be banked.

It sounds right at first sight, but I'm not sure if this is so in
practice. Perhaps it's because we have different methods of programming.
Just think about what the equivalent of the process I described above
would be if unbanked registers were a lot and we had more pages.

> Personally, what I really would have liked to have seen would be something
> more or less akin to the 8x51, but with some enhancements [far too late
> now, though]
> DIRECT MODE ACCESS:
> Addresses 00-0F: Special-purpose registers, much as they are now, but with
>   the timer stuff removed to make way for a new bank-switch register,
>   and possibly PRODL and PRODH.  To simplify the architecture, I'd also
>   probably make WREG read-only and re-add the movf instruction.

Ok, though I guess the WREG stuff wouldn't ease things much.

> Addresses 10-17: General-purpose RAM (possibly with PRODL/PRODH at 10-11),
>   accessible via movpf/movfp
> Addresses 18-3F: General-purpose unbanked RAM
> Addresses 40-7F: Eight banks of eight I/O registers.  The movpf/movfp
>   instructions would be bank-switched to select a group of eight, but
>   other instructions could access any register directly.

I think I like this idea (a separate RAM file), but I don't like having
the RAM area splitted.

> Address 80-FF: Bank-selected memory, using bits 3-7 of the BSR.
> INDIRECT MODE ACCESS via FSR0
> Address 00-FF: Bank-selected memory, using bits 0-3 of IBSR
> INDIRECT MODE ACCESS via FSR1
> Address 00-FF: Bank-selected memory, using bits 4-7 of IBSR

Two BSRs would be great, and the rest we've already talked about a lot...

> This architecture would allow indirectly-accessed memory [arrays and such]
> to be accessed cleanly in banks of 256 addresses, while allowing any
> indirectly-accessible location to also be accessed directly.  For
> applications that did not require direct access to all memory, a full 168
> bytes of "non-banked" direct-addressed storage would be available.
> Oh well, too late now...

Ok, but I in my opinion the kind of applications you're having in mind is
not as general as you're thinking.

Regards,

Andres Djordjalian
.....adjordjKILLspamspam.....aleph.fi.uba.ar

More... (looser matching)
- Last day of these posts
- In 1997 , 1998 only
- Today
- New search...