NEW: See my YANGTOS OS Development site.
RISC OS Asm and BASIC Fun : BLOG
Home Reference Blog Downloads Links
.

This is my blog, just a place for me to go on about whatever I feel like, usually related to RISC OS and programming, sometimes other CS related stuff, and sometimes just a bit of a rant.

This blog is done in hand edited HTML using !Zap on RISC OS. There is no fancy blog engine being used. In other words this blog is done the correct way :) .

.
NOVEMBER 25TH 2019 @ 11:30PM  Optimizing?
This is a rant that covers something very important

People now days think that the compiler will do all of the work for them in optimization. Worse yet many think that using a lot of resources is OK because all the modern computers have enough resources that it "does not matter".

The truth of the matter is that every CPU cycle counts, every byte of RAM counts, especially when running on modern systems. Firstly the less time you spend on the CPU the more time everything running has to use it, and the less RAM you use the more that is available for others to use. Hogging resoureces is BAD. Secondly the less CPU time you use the less electricity you use (and electricity is to be conserved more now than ever).

Disk Usage:
Then there is the over use of access to the mass storage device (Disk, SD Card, SSD, Thumb drive, whatever it may be). Many programs will only load a portion of there resources into RAM, even though much of what they leave on disk is often needed, making them frequently load resources from disk. This is a means of saving RAM on systems of the past, not of the present, every time you access any mass storage device you are putting ware on the device, and you are using more electricity, and stalling your program making it seem less responcive to the user.

The Normal Argument:
Developers often try to argue that using the extra resources is not that big of a deal anymore, even for programs that do a lot. That is a very poor argument, even more now days, as described above.

Some time ago I got a book on C++, as at that time it was a new language to me. The author did a good job of presenting the language, though in his chapter on optimization he said that the best method of optimization is to use a faster computer with more RAM. That is the single worste advice in history, it promotes poor coding. I threw that book in the trash. This seems to be the mindset that many programmers have, which is a very poor mindset.

Good Optimization:
Thus far the best means of optimization I have seen is to optimize the algorithms and there implementation. An optimal algorithm implemented optimally will often out-perform a poor algorithm implemented without thought to optimization, even when the good algorithm is running in a BASIC interpreter and the poor algorithm is compiled with a good optimizing compiler.

Any algorithm should be optimized to minimize the amount of disk/mass storage access, minimize the amount of memory used without sacrificing performance, and minimize the amount of time it takes to run. When this is done you can still have the fancy UI's, and the extra nicities, while seeming very responcive.

There is an importance to optimizing for responciveness as well. Doing so not only makes the application seem better to the end user, it also gives more time to the OS and other tasks, thus increasing the amount of time the CPU can idle, and reducing the use of electricity.

Always remember that no compiler, no matter how good, can compensate for poorly implemented algorithms, as they are just compiling the implementations of the algorithms.
.
NOVEMBER 23RD 2019 @ 10:30PM  Looking Forward, While Keeping the Old.

Thinking about where things are today, for the ARM based computers we use, causes me to think about what is going to last.

The oldest ARM design that I am aware of still being used in a current desktop computer is the ARM1176JZF-S implementation of the ARMv6 CPU, as used in the lower end of the Raspberry Pi range. This core was released in 2003, 15 years ago, and the if memory serves Raspberry Pi intends to continue to produce products based on this core until 2021, that would be a 18 year run.

Then we look back to the ARMv5 was only around from the late 1990's until around 2008. Look further back still and we find the ARMv4 was around from 1993 and used in desktop systems up until at least 2008, that is a lifespan of 15 years.

It would apear that the ARMv8 is going to be around for a while, and going to continue to support the 32-bit ARM ISA for quite some time to come. This makes it logical to make sure that anything created is ARMv8 compatible. The Raspberry Pi 3B and 3B+ simplify this a lot, as they provide the perfect ARMv8 platform on which to develop and test new software.

Depending on the software, there will continue to be those things that will need to run on everything all the way back to the ARMv2. As such care will be taken for those programs that will be useful to someone running an ARMv2 based computer. The appropriate minimum system where a given program could be really useful should be supported, while making sure that the program runs well on all newer ARM based RISC OS systems. The only exception to this rule would be those things that use hardware specific to a particular system.

The More Difficult Side:
On the flip side of the coin is to make sure that newer systems will run older programs, that can not be run natively on the newer hardware do to whatever incompatibilities. So the emulators like Aemulator will remain forever important additions to all systems meant to run RISC OS software, including the primary branch of RISC OS.

This issue even extends into my OS, as I intend to be able to run some RISC OS software as the OS matures.

.
NOVEMBER 22st 2019 @ 10:30PM  Interesting The Way Some Think About Bare Metal Programming in C:

I was pointed at a tutorial that someone wrote about Raspberry Pi Bare Metal programming in C, because it is well known that I do very little in C prefering assembly (and YANGTOS is mostly in C). This tutorial did so many things the least effecient way. Out of respect I will not say where it is or what it is called, unfortunately I was not able to contact the author to provide any help.

The particular tutorial I am speaking of, expected no artifacting on the display, and good performance without the page tables enabled. This tutorial did not even begin to mention the use of linker scripts to correctly order code until it was most of the way through. As we all know both of these are very important issues to performance. Worse yet he did not understand why runing code on a single core ignoring the other cores was slower on the Raspberry Pi 2B than in the Raspberry Pi B (4 core slower than 1 core), even though the other three cores are using a lot of bus time looping on the mailboxes while waiting to be brought up.

It became clear that he is not an assembly programmer when he setup his vector table (and a few other things before that). I can forgive that, it is understandable, as many people think assembly is hard and thus avoid it (even though Assembly is very simple, especially for the ARM).

The solutions to his issues would have been if he:
  1. Enabled the caches AND MMU with identity mapped page tables.
  2. Set the page table entries for the frame buffer to non-cachable.
  3. Woke up the other ARM cores and put them to sleep.
  4. Used more reasonable linker scripts than he ended up with.
  5. Used multiword access to plot to the frame buffer, instead of the bytewise meathod he did use.
This is another rant about the fact that there is some poor information out there. I did actually learn a couple of tricks when reading his tutorial, C spicific tricks, though tricks none the less.

I am glad that his tutorial exists, as it does show how to do much of what is needed. He also does highlight the importance of choosing the correct optimization switches when compiling C code. And he is definitely a C coder. I just wish I could get ahold of him to help him improve what he has, with some very simple changes.

.
NOVEMBER 22st 2019 @ 1:00PM  Spin Down, Time For a Moment of Fun:

I am going to be mostly concentrating on working towards a Raspberry Pi B/B+ Bare Metal 4K Scene Demo. This is to give my mind a little bit of a break, and just have a bit of fun, no worries about the best practice, or following this or that coding standard, Scene Domos are about breaking the rules to fit a lot into a very small amount of code+data (4KB total in this case, if all code it would give 1024 instructions, not much).

I am writing my Demo in ARM assembly, targetting the ARMv6 (RPi B/B+), using the BBC BASIC V built in assembler to assemble the code (readability). This is going to be a sudo-storyline demo, using a partial raytracer to render a nice display, after running through it will give the user the option of switching SD cards so that when it reboots the RPi they can return to there OS of choice. It will do a hard reboot of the RPi when it is done, so if the SD card is not changed it will repeat itself.

I am not going to give to much information about this Scene Demo until it is completed.

Do to the nature of coding a bare metal scene demo, there is a high probability of the mind wondering in a way that will also add to the progress of YANGTOS.

.
NOVEMBER 21st 2019 @ 7:00AM  Two things of interest.

I figured out how to get the YANGTOS Kernel to correctly boot in either a configuration that will support SMP, or one that will run single core.

I am also giving thought to making YANGTOS a hybrid multitasker. That is the already existing preemptive multitasking combined with cooperative multitasking. That is the kernel schedules and preempts each task at each prioity, though at the same time a task can poll, thus swapping itself out of the queue until the poll request is sastified, in some cases that would mean that all other tasks that poll will have had to done there poll depending on the nature of the poll request. This change could greatly simplify inter process communication, for tasks that choose to use it.

.
NOVEMBER 20th 2019 @ 5:30AM  A different approach to Task Scheduling.

I was thinking about task scheduling algorithms last night, and decided not to use a modified round robin. Instead I chose to replace that with a binary scheduler.

A binary scheduler takes advantage of the fact that binary numbers are based on powers of 2, and that when counting up in binary only one bit will change from 0 to 1 for each increment of 1 (except when rolling over to 0). This gives bits number of priority levels, and assures that every task will get a time slice, no matter what.

I have reduced the number of priority levels for tasks to 8, as higher numbers begin to go to long between calls to the lowest priority if you have any number of tasks in the other priorities.

Well I am off to update the kernel overview page to reflect this change. And going to release one function of untested code for the first time in my life.

.
NOVEMBER 19th 2019 @ 7:00AM  Why Do People Create Poor Code in C when adding Assembly?

Have you ever noticed that many people will write a C function just to call a bit of assembly code, though they rework the data a little in C making the Assembly code bigger than it needs to be. Thy will have 8 lines of C, 20 lines of assembly when all they needed was 5 lines of assembly and zero C for what they were doing.

People say I am odd for liking assembly language. Yet these same people will create C code that makes there assembly bigger and often slower. How does this work, does it make any since to anyone? Not me.

A Bit on My Preferences of C Coding:

I will admit I am a bit strange, as I prefer to use the old K&R style function declaration format, even though it does not allow for compile time type checking (and sometimes I take advantage of this to do tings that would require more typing to do with ANSI C function declarations and type checking).

I use ANSI C rules whenever I write anything that is going to be, or may be released to the view of others. That is only because I know that most people are more comfortable with ANSI C.

There are many that will use underscores to seperate portions of identifier names. Not me. Cammel Case is way more readable than underscores, so for my code the rule is avoid underscores, and use Cammel Case.

Though personally the one thing that some others do that is the worse thing to do to the readability of a progran is; using super long identifier names, the identifier does not need to tell its life story, it is just a name. Would you namy your child something like TheBoyBornOnTheDayAfterWeAteOutTookTwoHoursOfLabor? Then why do you try to name even less important things, the sections of code, such way too overly descriptive things. All that this does is make the code harder to read, as you can not quickly identify the identifier, you have to read it instead. Keep your identifiers short, and appropriate, and you have more readable and maintainable code.

My rules for identifiers are very simple:
  • Never excede 16 characters in length, try to stay under 10 charactors.
  • Should never contain more than 3 words.
  • Use Camel Case where it improves readability. Never use underscores.
  • Identifiers can use single leter representations of words, or omit vowels, etc. Sometimes this improves readability.
  • Identifiers should be simple in nature, like the name of a physical object (do you put your hat on your head, or do you put the round brimmed cylindrical flexible head fitting object on your assembly of bone and flesh that contains the major neuro network and has optical sensorary devices, as well as first stage food processing facilities and is covered in cariten strands).
  • Identifier names should be appropriate to what they are.
As you may have guessed this is a big one for me. I have turned away from many projects because of others abusing the use of identifiers, it is very often obsurd. Yes it is important for a label to be appropriately descriptive, though it is just a name, it does not need to tell its entire story (that is what comments are for).

.
NOVEMBER 18th 2018 @ 7:00PM  On HTML to Show C, ASM, and Other Source Code.

I have decided to put the c2html parser on the back burner for a while, wanting to concentrate more on actually getting the YANGTOS site better done. I did not get much done today other than a decent start on the converter.

As such I am going to be just using HTML preformated text code tags to put in code. Here is an example from one of the C programming for RISC OS tutorials I wrote years ago. The lack of comments is intentional for the purpose of the lesson it was with.

Fair warning, this example spans 3 files. One .c C source, one .h C header, and one .s ObjAsm/asasm assembly source.

main.c

#include "MWimp.h"

long TBlock[255], WData[255], *WDataTop;
long THandle;
long WindowH[2];
long BarIconH;
long Quit = 0;
CIconBlock BarIcon = {-1,0,0,68,68,0x3002,{"!t00wimp"}};
NewMenu("Wimp Tut 0",Menu0,2)


//**************************************************************************
char *strcpy(char *s, char *t){
  for(int cnt = 0; (s[cnt] = t[cnt]); cnt++);
  return s;
}


//**************************************************************************
void MClick(void){
  if (TBlock[3] == -2){
      switch (TBlock[2]){
        case 1: break;
        case 2: Wimp_CreateMenu(&Menu0,(TBlock[0] - 64),188);break;
        case 4: TBlock[0] = WindowH[0];
                Wimp_GetWindowState(TBlock);
                Wimp_OpenWindow(TBlock); break;
    }
  } else if (TBlock[3] == WindowH[0]){
      switch (TBlock[2]){
        case 2: Wimp_CreateMenu(&Menu0,(TBlock[0] - 64), TBlock[1]); break;
      }
  }
}


//**************************************************************************
void SelMenu(void){
  switch (*TBlock){
    case 0: TBlock[0] = WindowH[1];
            Wimp_GetWindowState(TBlock);
            Wimp_OpenWindow(TBlock); break;
    case 1: Quit=0x0f; break;
   }

}


//**************************************************************************
void PollLp(void){
  while (!Quit){
  long r = Wimp_Poll(0x2301,TBlock,(long *)0);
    switch(r){
     case 2: Wimp_OpenWindow(TBlock); break;
     case 3: Wimp_CloseWindow(TBlock); break;
     case 6: MClick(); break;
     case 9: SelMenu();
       break;
     case 17:
     case 18:
      if (TBlock[4] == 0) Quit = 0x0f;
      break;
    }
  }
}


//**************************************************************************
void CleanUp(void){
  Wimp_CloseDown(THandle,0x4b534154);
  return;
}


//**************************************************************************
int main(void){
  THandle = Wimp_Initialise(310,0x4B534154,"Wimp 0",(long *)0);

  BarIconH = Wimp_CreateIcon(0,&BarIcon);

  Wimp_OpenTemplate(".Templates");
  long *toff;
  if (!(toff=Wimp_LoadTemplate(TBlock,WData,WData+64,"main\0"))) {
    CleanUp(); return 0;
  }
  WindowH[0] = Wimp_CreateWindow(TBlock);

  if (!Wimp_LoadTemplate(TBlock,toff,WData+256,"info\0")) {
    CleanUp(); return 0;
  }
  WindowH[1] = Wimp_CreateWindow(TBlock);
  Wimp_CloseTemplate();

  Menu0.i[0].f = 0;
  Menu0.i[0].sub = WindowH[1];
  Menu0.i[0].icf = 0x07000021;
  Menu0.i[1].f = 0x80;
  Menu0.i[1].sub = -1;
  Menu0.i[1].icf = 0x07000021;
  strcpy(Menu0.i[0].name, "Info...\0");
  strcpy(Menu0.i[1].name,"Quit\0");

  PollLp();

  CleanUp();
  return 0;
}


.
MWimp.h

#ifndef __MWimp_h__
#define __MWimp_h__

typedef struct {
  long f;
  long sub;
  long icf;
  char name[12];
} MENITEM;

typedef struct {
  char ttl[12];
  char tfc;
  char tbc;
  char wfc;
  char wbc;
  long w;
  long h;
  long vg;
}MENU;

#define NewMenu(ttl,name,cnt) struct{MENU m; MENITEM i[cnt];} \
        name ={{ttl,7,2,7,0,96,44,0}};

typedef struct {
  long x0,y0,x1,y1;
  long flags;
  union {
   char txt[12];
   struct {
    void *data[2];
    long v;
   }d;
  }d;
}IconBlock;

typedef struct {
  long Win,x0,y0,x1,y1;
  long flags;
  union {
   char txt[12];
   struct {
    void *data[2];
    long v;
   }d;
  }d;
}CIconBlock;

long Wimp_Initialise(long ver, long magic, char *name, long *msglist);
long Wimp_CloseDown(long thandle, long magic);
long Wimp_CreateIcon(long np, CIconBlock *icn);
long Wimp_Poll(long Mask, void *block, long *pw);
long Wimp_PollIdle(long Mask, void *block, long rtime);
void Wimp_CreateMenu(void *m,long x, long y);

void Wimp_OpenTemplate(char *FileName);
long *Wimp_LoadTemplate(long *buff, long *ind, long *endind, char *Tname);
void Wimp_CloseTemplate(void);
long Wimp_CreateWindow(long *buff);
long Wimp_CloseWindow(long *buff);
void Wimp_OpenWindow(long *buff);
void Wimp_GetWindowState(long *buff);

#endif


.
Wimp.s


  AREA |main|, CODE, READONLY
  ENTRY
  EXPORT PutS, Wimp_Initialise, Wimp_CloseDown, Wimp_CreateIcon
  EXPORT Wimp_Poll, Wimp_PollIdle, Wimp_CreateMenu
  EXPORT Wimp_CreateWindow, Wimp_OpenWindow, Wimp_CloseWindow
  EXPORT Wimp_OpenTemplate, Wimp_LoadTemplate, Wimp_CloseTemplate
  EXPORT TemplateFontRef, Wimp_GetWindowState

PutS
  SWI   &02
  MOV   R15,R14

Wimp_Initialise
  SWI   &400C0     ;SWI Wimp_Initialise.
  MOV   R0,R1      ;Return task handle.
  MOV   R15,R14

Wimp_CloseDown
  SWI   &400DD
  MOV   R15,R14

Wimp_CreateIcon
  SWI   &400C2
  MOVVS R0,#0
  MOV   R15,R14

Wimp_CreateMenu
  MOV R3,R2
  MOV R2,R1
  MOV R1,R0
  SWI &400D4
  MOV R15,R15

Wimp_Poll
  SWI   &400C7
  MOV   R15,R14

Wimp_PollIdle
  SWI   &400E1
  MOV   R15,R14

Wimp_CreateWindow
  MOV   R1,R0
  SWI   &400C1
  MOV   R15,R14

Wimp_GetWindowState
  MOV   R1,R0
  SWI   &400CB
  MOV   R15,R14

Wimp_OpenWindow
  MOV   R1,R0
  SWI   &400C5
  MOV   R15,R14

Wimp_CloseWindow
  MOV   R1,R0
  SWI   &400C6
  MOV   R15,R14

TemplateFontRef
   DCD -1
Wimp_LoadTemplate
  LDR   R4,TemplateFontRef
  MOV   R6,#0
  MOV   R5,R3
  MOV   R3,R2
  MOV   R2,R1
  MOV   R1,R0
  SWI   &400DB
  MOVVC R0,R2
  MOVVS R0,#0
  MOV   R15,R14

Wimp_OpenTemplate
  MOV   R1,R0
  SWI   &400D9
  MOV   R15,R14

Wimp_CloseTemplate
  SWI   &400DA
  MOV   R15,R14

  END



.
.
NOVEMBER 18th 2018 @ 6:30AM  YANGTOS Update.
The operating system project has a name. YANGTOS stands for Yet ANother Goliath Tiny Operating System. YANGTOS is pronounced like bang toss with a Y sound instead of the leading B.

YANGTOS will be distrubited under a 2 clause BSD license.
.
NOVEMBER 17th 2018 @ 11:00AM  OS Site.
Today I am working on the section of this site dedicated to the new operating system development. This is going to be interesting to figure out, so please bear with me if it changes a good bit for a while until I figure it all out.

Also I have decided that when the OS gets that far I am just going to port a C Library for the BSD ABI implementation.
.
NOVEMBER 16th 2018 @ 6:30AM  Starting an OS project for teaching OS development.
I am begining the process of writing a microkernel operating system for the purpose of demonstrating some of the concepts of OS design. The intention is to target Raspberry Pi 3B/3B+ BCM2837 hardware for the first version, with concentration on keeping it as portable as possible. To create a user space I will be implementing a BSD personality module for the OS, so that the NetBSD userspace can be ported.

The C library for use in the BSD user space is still open for debate. I am not sure if it would be worth implementing at least a portion of the C library over again for the purpose of extending the knowledge base covered. Though it is a long way from getting that far at this point.

CURENT STATUS OF THIS PROJECT:
Today I managed to get a successfull boot of all 4 cores on the RPi into SVC mode, enable the caches, enable the MMU, and have a small rectangle displayed on the Raspberry Pi frame buffer for verification of status, and mapping (as the frame buffer is remapped to test the MMU).

I am still not sure of where to put the main project on this site. I may create a subdirectory, and put this project there seperate from this RISC OS site.
.
NOVEMBER 16th 2018 @ 3:00AM  The Joys of 3D.
I am working on a simple software rendered 3D engine, with the goal of implementing a simple though user friendly slicer to create gcode for 3D printing from STL files. It works out that this kind of 3D engine is a lot simpler than ever expected, not as easy as a raytracer, though still very easy.

This shows a lot of how fast modern systems are, I remember when we had to use every dirty trick in the book to get a software rendered 3D engine to be usably fast, and now it is very easy to implement one without any dirty tricks at all.
.
NOVEMBER 15th 2018 @ 3:30Pm  Not Liking ARMv8
One thing that keeps bugging me about using the Raspberry Pi 3B is the core tempurature being so high, when running one underclocked ARM Core, and barely touching the GPU (I am running RISC OS). The energy density must be quite high for that to be the case. That kind of turns me off to the BCM2837, and I am not sure if I would be willing to try another ARMv8 board.

Then there is the software incompatibility, which is not that big of a thing, as I still use a lot of 26-bit R15 stuff which requires some form of emulation to run anyway. Though combining the two issues is a bit much for me. I am going to be unplugging my Raspberry Pi 3B after I finish posting this message, and replacing it with an extra Raspberry Pi B+ (BCM2835 based, ARMv6).

EDIT November 16th 2018:
I am using the RPi 3B again for RISC OS. I have decided not to worry so much about the thermal density, as it is important to show the usefulness of RISC OS on as many ARM based systems as possible.
.
NOVEMBER 15th 2018 @ 12:30Pm  I am Back
I am back in contact. Looking forward to sharing. I should be updating this site a little at a time for the next few days.

I was out of contact do to having some medical issues, so now I have recovered enough that I am back.
.
Older Entries
.
This page maintained on RISC OS using !Zap.
Copyright 2016-2018 David Cagle (AKA DavidS).
PAGE LAST MODIFIED ON NOVEMBER 25TH OF 2018