Do you see any areas of improvement here?

Go To Last Post
83 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will try it!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Running the test now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Valgrind is an EXTENSIVE dev tool for PC software.
embedded too

Hardware and software tools for embedded developers | Static Analysis and Metrics Tools by Jack Ganssle

[near bottom]

...

I [Matthew MacClary] implement the core of my functionality for embedded systems as regular Linux programs, and then just pass a define variable to the compiler when I want to to pull in the microcontroller specific functionality. 

...

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just to get a real idea of where the time is spend, you could show all the ASM code the AVR get through (single step) to emulate a simple NOP instruction.

 

If I would do it in ASM I would probably fix Y to PC and Z to a page with 256 ijmp so a nop would be

 

top:

LD r30,Y+

IJMP

 

 

;Code for  nop

rjmp top

 

So that is 6 clk

7 if r31 should be loaded.

 

 

   

Last Edited: Sat. May 23, 2020 - 11:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>One small test could be to place A in r16 , and perhaps F in r17

 

A bit faster...

 

moved A to R16 and	23803464422/9753.30/1e6 = 2.44055 MHz
flags to R17, also
unioned flags for
pop/push

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do you deal with all the flags? 

Other than P there is a close relation between the other flags on a 8080 and a AVR 

 

8080 : AVR

CY    : C

AC    : H

Z      : Z

S      : N

 

So it could make sense to get those from SREG if there is a safe way with your compiler. 

But they are placed different. So perhaps a look up with those where there is 0 on P's bit, and then lookup P and or it on (0 or 4 in LUT)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've gone back and forth with various things with them.  I've kept them as independent uint8_t's, I've tried dealing with them all together as a uint8_t using masks like flags|=_BV(CARRY_bp), and I've tried bit fields.  The zero and sign are easy enough to calculate, but I pull the parity from the table.  I also tried bringing in the zero/sign/parity all in from the table at once.  Now that I have them back in a union so they can be accessed as a byte or as a bitfield, I should probably try the combined parity-sign-zero table again and see if that shaves any time off.

 

Your point is very on spot, if one were coding an emulator like this in assembly, you can take advantage of the similarities between instruction types.  I was actually thinking this when I was writing it in C that not having things like flags exposed works against you when coding something like this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I once started to write an AVR simulator in AVR C (hopefully not as mad as that sounds - the real idea being able to fetch and execute AVR code from SRAM) and one if the reasons I gave up was trying to get the flag values from the run of the C simulated opcode into the virtual flag register. It's quite a challenge. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Absolutely clawson.  It is an odd thing because you always hear how close to the hardware that C is, but it is really abstracted from it when you think in terms of registers and flags.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know it's kind of old but here is a thread with some thoughts:

 

https://www.avrfreaks.net/commen...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had a Commodore PET with a whopping 8k of memory comprised of 64 2102 chips. It had a little bitty CRT built in (about 9 inch with green P1 phosphor), a built in cassette tape for saving and loading programs and a horrible "chicklet" keyboard. I put a fan inside it because the 2102 chips would get hot and then the display would go crazy and the computer locked up.

 

I had the "Programmer's Toolbox" rom for it - always used it's "renum" statement for Basic programming.

 

The good ole days(?)

 

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Was that a prototype ?

 

A normal PET used 16  6550 SRAM (or 2114.) 

 

And the later versions with DRAM (rare here in only 8 k ), used  8 2108 DRAM

(I remember that the board layout was so you could add more RAM, to prevent people from doing that they drilled holed in the PCB, so we soldered the extra chips on top of the existing chips (two pins bend out) and fished extra signals elsewhere. I can't remember exactly how it was, but I have done it a lot to make Atari ST520 to 1040)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1


I've got Altair 8K BASIC running on the mega1284 now:

 

cid:image001.jpg@01D64037.EEB0EE40

 

I made a small program to calculate the location of a circular tube socket:

 

10 INPUT "Pins";P

20 INPUT "Diameter";D

25 R=D/2

30 INPUT "Offset Degrees";O

40 FOR A = 1 TO P

50 PRINT "Pin";A;

51 PRINT TAB(10);"X=";SIN(((A-1)*360/P+O)/57.2958)*R;

52 PRINT TAB(30);"Y=";COS(((A-1)*360/P+O)/57.2958)*R;

53 PRINT

60 NEXT

 

 

I wrote a small FAT8 file system for it so I can load and save chunks of memory to an 8 pin EEPROM that I'm going to put in a ZIF socket as a "drive".

 

It is still just in the beginnings of a project, but fun to mess with.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2


  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Getting an error message with another C file in the project:

 

Warning        fixed register r16 used to pass parameter to function   

 

Under the C misc I have:

-std=gnu99 -ffixed-2 -ffixed-3 -ffixed-4 -ffixed-5 -ffixed-6 -ffixed-7 -ffixed-8 -ffixed-9 -ffixed-10 -ffixed-11 -ffixed-16 -ffixed-17

 

Shouldn't it know to not use r16?  or did it have no choice because I took so many registers from it?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alank2 wrote:

Shouldn't it know to not use r16?  or did it have no choice because I took so many registers from it?

Possibly.  Impossible to say unless you show some code.  Could also be that it's pre-compiled library code in the form of a *.a archive.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No pre-compiled code.  I added a new function to some code I have (i2c.c):

 

uint8_t i2c_Command(uint8_t AControl, uint8_t ADualAddress, uint8_t AAddress1, uint8_t AAddress2, uint16_t ALength, uint8_t *AData);

 

I did try to include an H file that defines the registers, but it didn't make a difference.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alank2 wrote:

uint8_t i2c_Command(uint8_t AControl, uint8_t ADualAddress, uint8_t AAddress1, uint8_t AAddress2, uint16_t ALength, uint8_t *AData);

That's 12 bytes.  Note that unit8_t parameters are still passed as two bytes, with the MSB ignored.

 

Have a look here:

https://gcc.gnu.org/wiki/avr-gcc#Calling_Convention

 

So your arguments would normally be placed in:

AControl     in R24
ADualAddress in R22
AAddress1    in R20
AAddress2    in R18
ALength      in R17:16
AData        in R15:14

It's unclear to me how the compiler will handle this in the face of -ffixed-16.  One might expect it to adjust the calling convention to accommodate it, but that might be an unreasonable expectation.

 

Are you certain that all translation units are being compiled with -ffixed-16?

 

EDIT:  The only reference to -ffixed in the above link is w.r.t. function prologues and epilogues, not w.r.t. the calling convention.  A bit more digging may be need to get a documented answer, but you could also run a few tests.  @skeeve would disapprove, though, of such stick-poking ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Tue. Jun 23, 2020 - 05:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A possible workaround would be for you to place all of the arguments into a single struct and pass those to the function as a single argument.  That way, it would be only 8 bytes (assuming the correct struct packing attributes or build options are used), and would be passed in R25:18.  The overhead involved in so doing might nullify the gains of fixing r17 and r16 in the first place, but that might be mitigated by maintaining that struct throughout your project, anywhere those arguments are needed.  Whether or not that would help would of course depend on when/where/how each member is used.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have:

 

-ffixed-2 -ffixed-3 -ffixed-4 -ffixed-5 -ffixed-6 -ffixed-7 -ffixed-8 -ffixed-9 -ffixed-10 -ffixed-11 -ffixed-16 -ffixed-17

 

in the C misc other flags area which I would think would apply to all units being compiled.

 

I was thinking of struct'ing the parameters anyway so that may what I do or I may lighten up a bit on reserving registers - that was a test to see how much performance I could crush out of an 8080 emulation core.  There may be some registers that are more valuable than others and I could reserve less.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alank2 wrote:
There may be some registers that are more valuable than others and I could reserve less.
Review the whole page at the link I posted in #70, it may help you select the best registers to reserve.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will joey - thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alank2 wrote:

I have:

 

-ffixed-2 -ffixed-3 -ffixed-4 -ffixed-5 -ffixed-6 -ffixed-7 -ffixed-8 -ffixed-9 -ffixed-10 -ffixed-11 -ffixed-16 -ffixed-17

Can't help thinking you may be over-doing the register binding thing. I can perhaps understand where one uint8_t or a uint16_t might need to be reserved for fast passage of data from ISR to main() or something but TWELVE registers ?!? If the code is so speed sensitive why not just implement the relevant bits in pure Asm?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You make a good point clawson, I did that many just for testing to see what it would do.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Remember that the more you constrain the compiler from doing its own preferred register allocation the more work (stacking and moving registers) it's going to have to do all over the code in other places where it would otherwise "run out" of registers .So binding a register is something that should be reserved for only very special jobs.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Agreed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I finally got some pcb's in for this project and built on up.  Much nicer to work on that breadboards!  I've got a lot of firmware still to write, but it can run Altair 8K BASIC and I can stop it and step instructions so far.  It has an i2c RTC, two EEPROM's for storage, and an I/O expander.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Alan,

 

Nice looking project!

(And it even runs my favorite language!)

 

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks DocJC - I'm pleased with how it turned out so far though I've got a lot to do on it.  Have you had any time to work on anything lately?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 Have you had any time to work on anything lately?

smiley,  Yes!

But I don't wish to derail your Thread.

So just a quick image or two.

 

The first one has a Nano on the back side of the board and a Bosch BME280 sensor (purple breakout board) to measure atmospheric pressure, temperature, and humidity.

I did this to measure the "negative pressure" in several of my Emergency Department's negative pressure rooms as Covid-19 unfolded.

There is a switch in the hall to turn the negative pressure on/off for the room, and its display and my measurements are reasonably close.

 

The second is a small DIP'able AVR128DA48 breakout board.

I decided I'd better see what the new chip lineup has to offer.

The breakout has 3 & 5 V regulators, but no USB built-in.

I tried to spark some interest in getting Bascom to support the chip, but struck out.

So I had to write, (i.e. mostly copy from the web...), my first C program to flash the LED to see if the board worked.

 

The third one looks a lot like the first one, but it has an Xmega32E5 under the GLCD.

Projects tend to generate sub-projects, and I needed an audio signal generator for a test signal.

My old Heathkit vacuum tube signal generator went snap-crackle-pop last time I plugged it in, so I made this little DDS signal generator.

The op-amps to the right of the GLCD filter the output.

The x1 and x1 are for several SW and HW attenuators.

The main project this supports is still a work in progress.

 

Try not to laugh too hard.

The astute observer will notice that the optional wall wart power supply barrel connector has a wall between it and the rear knock out for the power plug... blush

That's why I call this a Prototype !

 

Spring break and Summer vacation are done, so I'm back to snippets of time to work on stuff, instead of some dedicated days in a row.

But I'll still tinker as able!

 

Take care,

 

JC

 

 

 

 

 

 

    

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>Try not to laugh too hard.
>The astute observer will notice that the optional wall wart power supply barrel connector has a wall between it and the rear knock out for the power plug... blush

>That's why I call this a Prototype !

 

That's not so bad - the ONLY defect on my trainer board above is the DC barrel power connector.  I grounded the pin that can be used to detect whether a connector is plugged into it or not and left the barrel isolated instead of grounded.  Thankfully it is pretty easy to fix by filing away a little solder mask and grounding that pin.

 

Sounds like you are getting a ton done!  I like the pressure sensor, very cool.

 

We need another one of those everyone show off their project threads.

Pages