Code and APCS
Rick Murray (539) 13840 posts |
I hear that’s even worse, but differently so (namely “boosting” involves an actual copy, not just tagging another like, so getting rid of unwanted content that has been boosted by the sorts of unpleasant people that inhabit Twitter these days is a game of whack-a-mole with loads of copies of something floating around instead of just the one).
Comment sufficiently, but don’t hand hold. Not in assembler. The best thing anybody who isn’t familiar with assembler can do is use anything else. Pretty much anything and everything else (even C) will handle tedious grunt work like register assignment, working out what to stack and unstack, where to stuff data, and even how to call functions. Those people who have experienced their machines completely locking up? Could be something as dumb as a rare race condition meaning a different number of registers pulled off the system stack as were put onto it. Result? Kablooey. The machine corpses quicker than a valley girl in a field full of zombies. On the other hand, if you’re doing it just for the sake of doing it… carry on. ;)
You saw the show photos, right? We’re pretty much all the older grumpier ones (yes, I count myself). And god knows plenty of Brits like to complain over a brew or a pint. 1
I think one of the problems we have is that there’s no central repository of information. I’m as guilty as everyone else, with the random stuff on my blog, your tweets, people referring to stuff published in a magazine somewhere… there’s no centrality. Ditto, by the way, software. We have two different ways of packaging and a plethora of websites (yup, guilty again). Which means that, even if most of us are old and grumpy 2, this place is a fairly essential resource even if just to join the dots.
It’s documented in the PRMs. Google was…useless…so I gave up. The simple form of APCS is that R0-R3 are trashable by the code being called, other registers used should be preserved. You can pass values on entry in those registers, and a result is expected in R0. The convention used in a lot of DeskLib is that on exit R0 is either NULL or a pointer to an error block. That’s not part of APCS but might be useful? If your code is fairly simple, that will probably suffice. It works for me. Beyond that, you’re looking at stack frames (and unwinding), passing >4 items using the stack, different ways of passing FP registers, and loads of other implementation details. Refer to the PRM. Section 88, or Appendix C, about two thirds of the way through book 4 describes the older 26 bit APCS. A potentially more readable and up to date version is in section 16 “Assembly language interface” of the C/C++ guide, with a full definition as appendix G of the Desktop Tools guide, but both of those are a part of the DDE… 1 Brew tends to mean tea, so pint means beer, and “brewski” means “oh Christ an American” ;) 2 You’ll have to forgive Brits being spectacularly grumpy right now. Their Prime Minister is hailing the Brexit Benefit of the advantages of Northern Ireland being a part of the UK and a part of the EU. |
Paolo Fabio Zaino (28) 1882 posts |
It’s “noisy”, but that can be solved with subscribing to specific tags, which is nice. The issue for me is I don’t use socials or forums to engage in regular life things (like politics, events etc.), I use them just to follow specific technical matters that I am interested into. So, obviously, I am not an ideal user, hence not sure if it’s “socials are bad” or if I am just a “bad user for them”.
I think I owe you a bit of clarification. The whole thing is just because I need to complete a set of Transient utilities for my DME project, for which I was writing a C Library (the uCLib aka “micro C Library”) to finally allow writing Transient executables in C, because ROOL still seems to have no support for those in the DDE. However, I have less free time at the moment for RISC OS coding, so the uCLib is probably going to be delaied and so I quickly developed a bunch of Trasient utilities in ARM Assembly and asked if the code was readable enough for people on twitter or if it needed to be made even easier to read for non experienced assembly developers. In 2026 it will be 40 years for me of professional career in Software Engineering (and a very succesful one too thanks God, especially given the times we are living in), so for me ARM Assembly (and also most of x86) is as natural as probably BBC BASIC for many here. That is not a good thing when trying to write code that should be readable for people not so familiar with ASM, hence I asked if that form was readable enough or if it needs more improvements.
Yes, I am in one of them lol, yes the average age is high (I am not that young myself either), but that doesn’t mean we can’t be just nice with each other. Some folks here is clearly insecure (which isn’t something related to age or country of origin btw) or in some sort of competition which is ok, I mean it’s common although probably completely useless on an OS that is technically dead. And it doesn’t help to fix things and make things better, it’s just an annoying “fly in the ears”. At this point there isn’t much left to say, after 30 years the OS is still in a “pre-tech history” state, so no one, literally no one here was able to solve the big issues, hence there isn’t much to play “the smartest guy in the room”, isn’t it? And, if in doubt: other OSes went from crappy ASM to way more, there are OSes out there written by a single person (and for fun) that give miles to RO, so why even bother try the “fake aggressive”/grumpy/etc?
True.
I agree, which is why sometimes I try, but (goto 10 lol). There is one thing, however, I don’t fully agree with you. I mean, for most people a search engine is the central piece of everything they do on the internet these days, so on that regard things are ok even the way they are, as long as we make them easy to search and find on whatever search engine.
:) just mentioned the search engine… However, IMHO, the PRM should be published on-line (and probably it is?), I mean we have like 30 web site publishing Linux man pages these days, so I think it’s probably time for RO as well if it hasn’t be done already. BTW, thanks for the pin, I’ll search on the PRM and, if not available on-line, will write an article on my blog with the data. Again, if someone is happy with correcting my English, then someone could re-publish it fixed on ROOL’s Wiki maybe?
Given we are talking about Transient (Utilities) on this particoular case, I have obviously the initial r0,r1 and r12-r14 pre-sets, but that could be quickly fixed with a macro that copies values around eventually. When I quit my code, if there was an error, I should set V flag and set r0 to a pointer to the the error block, so that should be fine yes, just point r0 to NULL as you say for regular exits.
Yes we are talking of transient code, so nothing ultra complex, however some of the tool does quite a bit of data manipoulation, but again nothing that requires magic souces, which is why I had the idea of making it as readable as possible btw. Again thanks for the suggestions :) |
Rick Murray (539) 13840 posts |
When I’m referring to the average RISC OS user as grey haired and grumpy, I’m very very careful to make sure that I include myself in that category. Which is why this is Not Good:
It’s one thing to point out and acknowledge the flaws and limitations, maybe even a bit of head banging over some of the decisions being taken (cough, network stacks, cough), but to phrase it like that makes it come across as an attack. Vindictive, almost. Now, it doesn’t bother me, I lack tact and have no filter, but it may bother others, so it’s worth considering thinking not only of how you feel when writing something, but also how it will be received. Would you say the same things to us in person? (and if yes, are you built like Dwayne Johnson? ;) ) Now, back to the scheduled programming:
The particularities of the entry conditions to a piece of code do not need to relate to what sort of standard you use within it. How transients start and finish is only of relevance at the start and at the end. Otherwise, so long as you respect the conditions (if anything needs preserved), you can do what you like in the middle.
👍 Some people try too hard to be clever and optimise beyond the point of sanity. It causes problems later on. Clarity is king. |
Paolo Fabio Zaino (28) 1882 posts |
Oh sorry, it wasn’t my intention. Just tried to picture the (surely possibly cold) reality compared to other OS out there, but again, nothing on the lines of an attack or vindicative. I am ok with what it is, it’s a fun hobby for me.
Oh I totally understand that, I too still get people trying to teach me C or ASM etc ahahah it’s ok I don’t mind, some people just need to talk that way. The reason of my directness isn’t meant to hurt, it’s more pragmatism. In this very forum we tend to have a fairly-constant re-emerging of situations that are beyond resonable and btw I have seen you losing your temper with some folks that was not even ok like in their mind state, so, while I appreciate your suggestions (I really do), maybe (with touch) may I remind that I am not the most direct one on here? ;)
True, seen it many time in my career, but it’s also true the inverse. A lot of people don’t fully undertsnad the implications of blidly applying the rules of “Clean code” for example, and that believe me can have some serious repercussion over performance. For instance Polimorphism over using if/then statement in the code can have serious bad performance effects if not applied correctly and carefully (classes design, move semantics in C++, owrnership in Rust etc.). Generic programming can cause troubles with both compiler and runtime (in Java) performance, or object space overhead (in C++) depending on how templates are instanciated for example. In the other hand, with lower level languages, too many levels of indirections can become hard to debug, but at the same time they help abstracting code to make it more readable. However no indirection at all makes code hard to adapt to the systemic change of requirements which are a natural part of software lifecycle. There is so much, and experience is probably key. However in this particoular case, havign no idea abotu what other (an dinterested) people know, the best approach IMHO is to ask, beign direct lol “Do you understand this code? If not what else could I do to make it more readable?” :) I guess as Aristotle’s philosophy suggests “In Medio Stat Virtus!” |
Rick Murray (539) 13840 posts |
Ditto. Also means I don’t have to learn any of this trendy newfangled stuff that would help me create an app in a fraction of the time. ;)
If I were perfect, I would be the central edifice of a religion. But, yeah, trolls spewing endless gibberish and not taking a hint does tend to get annoying and there’re only so many cups of tea I can realistically drink…
😜 That being said, I don’t think I’m the most direct one. I’m just the one that never shuts up 1. But, then, this is pretty much the extent of my social circle…
I’ll have to take your word for this, I don’t have or use a compiler that offers such a thing. However, it does come down to knowing your tools, and in a way, falls right back to “the best optimisation is a good algorithm”. For example, I tend to write bubble sort functions when I need to sort things. Because I suck at maths and bubble sorting is simple enough that I can understand how it does what it does. But I’m fully aware of its limitations (my comments usually contain disparaging notes about the following code ;) ).
But at what limit? It seems so much stuff these days is frameworks upon frameworks upon frameworks, and there’s maybe a dozen levels of libraries and associated function calls in between you saying “plot a dot on the screen” and something setting a word of memory to make it happen. This being said, at application level, indirection and abstraction mean different things than those words when looking at the system as a whole.
True. In the beginning it was a simple self written HTTP fetcher. Then it was SecureSockets, and finally it was the URL fetcher (with AcornHTTP and AcornSSL). Somewhere along the way, caching was added so that maybe no fetch actually happened, it just pulled the data from the cache. The function calling the fetcher? Has no idea. It just says “get this please” and expects a response of some sort (yes, here it is or nope, failed). How this actually happens doesn’t concern the calling code. It’s just how modular programming is supposed to work. The program has APIs within itself in order to get stuff done, and breaking it into useful sections means stuff can be updated independently of other parts without causing loads of breakages. 2
Be careful. Around here, somebody might suggest “write it in BASIC”. ;)
Oh, Latin! Here’s the Latin philosophy I agree with: 1 I will soon, only forty six posts to go! 2 …in theory. |
Paolo Fabio Zaino (28) 1882 posts |
Just for the sake of the (inspiring) chat, actually we do, GCC on RO and I believe also DDE C++, but yeah I understand what you meant.
True, I’ll be very honest: I have no idea. XD Some may argue that is for rapid application development, and that it’s kinda true, in the sense that there are types of applications or components of an application that are very well known coding forms (aka we don’t reinvent them, we systematical code them in a very similar design). The Frameworks should be the answer to this, you no longer code the already “standardised” code, you just reuse it. Given that everything is a pipeline or processing path (or whatever is the British English way of defining it) insted of reusign a function someone thought that we shall reuse an entire processing path. Now here is where the problem starts. Reusing a function or even a Class (when it’s concise and simple) it’s easy, while sticking to a processing path is not always so. For instance, not everyone sees the entire processing path the same way a framework does. Not to mention that having to learn multiple frameworks can be hard and learn and adhere to a process path can also be hard (in the end we do not think all of us in the exact same way!). On top of that, given we have framework for (for example) create RESTFul APIs, then frameworks to process the data with HW acelleration on the GPUs, then framework to serialise and deserialise data because the two previous framework may require the data to be presented in a different structure, “boom” you get into the “web” you were describing. Does it makes us faster at building solutions? Yes it does. DO we build faster and better solutions with this approach? Actually not always.
Indeed, and in my original comment I was not refering to the “frameworkification” of modern software engineering. I was merely refereing to the way we may code even in the good olde C writing our own libraries. But there is another very interesting concept also related to abstration, the so called leaky abstration which may explain why we are not always coding efficient soltuions.
Ahahahah XD – What am I laughing at… actually you are saying the truth! :D This chat is inspiring me and not sure if it’s a good thing ahahahah XD , in a coffe break I decided to try and see if the old DDE C++ could do some design patterns, so I started from the easiest one to code (not to understand according to the many blog on C++) the Singleton and what do you know, it works really well: https://twitter.com/PaoloFabioZaino/status/1631031579714650119 Now I need some food, but I think I’ll try to implement some more design patterns while eating my steak, who knows what DDE will do :)
Hahahahaha very true! XD May I mention that (even not being an expert, so thake this with a pinch of salt), but I think it should be: Had no time to check, as mentioned about I am busy cooking a steak! :D |
GavinWraith (26) 1563 posts |
What is the right word for the opposite of abstraction? Whatever it is, striking the right balance between it and abstraction is an interesting question. The level chosen for a software problem may not necessarily be the same as that for teaching. We have all learned the lesson that assembly language is a hopeless choice for anything but tiny snippets of software – hopeless for lots of reasons. Yet when it comes to teaching how computers work, I think it unavoidable, even if all the salient aspects of modern CPUs are oversimplified out of existence. @Rick Your blog, and the archived Frobnicate material, seem to me to be a very inspiring record of how you have learned new stuff, and acquired new skills, over the years. I bow three times in a southerly direction, and I suggest that there are many young persons who could find much education and solace from your example. @Paolo I had hitherto overlooked the ABC compiler among ROOL’s offerings. But of course it is now an interesting alternative to GCC as a runtime system with VFP. It does not have the libraries or the universality of C, but it does have the BASIC assembler. A project worthy of Don Quixote would be to transpose Lua from ANSI C to ABC-BASIC. Etymological PS. I saw a YouTube video explaining where the word ciao comes from. It was tuus humillimus sclavus sum, spectabile domine . |
Colin Ferris (399) 1814 posts |
It seems that the 26bit converter prog Amulor uses it own Clib routines – so it can be soft loaded early. I wonder if this Clib file could be added to a Transient prog so that progs could be written in C instead of ARM? |
Chris Mahoney (1684) 2165 posts |
Low-level, I suppose, although maybe that’s going too far in the other direction. |
Stuart Swales (8827) 1357 posts |
Concretion! Thus spake the geologist. |
Paolo Fabio Zaino (28) 1882 posts |
Indeed Gavin, indeed. Given my ENglish is limited (and can cause troubles apparently lol) here is a video of someone explainin the concept I shared before in a much better way I possibly can with the language, in the end what is required to me at work is to know these concepts extremely well, and that is not a problem. https://www.youtube.com/watch?v=tD5NrevFtbU Besides the specifics of the video, it clearly highlight that blidly following any advice will almost certainly lead to problems. Hence the balance between Abstraction and Concretization (where Concretization is the inverse of abstracting, probably in British English it should be Concretisation? No idea tbh). However for the terminology there are actually some issues, for instance, abstraction is used as “generalisation” (or generic) hence the opposite should probably be specialisation. For the balance, what I have learned from my career is that the omnipresent “it depends” applies here a lot. In other words the methods that should be developed as specialised instead of abstracted should be decided on each specific situation, unless the project is something so standard that doesn’t require such an approach. Also, the Agile methodologies will dictate that it doesn’t matter mutch, as we can always specialise through refactoring when it becomes more clear that such component requires specialization. Now refactoring is another headache in professional world, because some company insists on tracking it as a separate task, and that is a mistake. Refactoring is constnat and continuous, every single developer every time we face our code we almost always do some refactoring activity, so it’s part of the development process as an stage of it and not as a separate task. And finally, programming with interfaces allow kinda both worlds to coexists. And this is another story btw :)
I am not sure how much gain there is in compiling BBC BASIC through ABC BASIC compiler to be honest. Yes by disabling Escape and designing BBC BASIC code to do quite some math it seems to gain performance, but otherwise it doesn’t seems to benefit much. I haven’t tested every possible option, but I did do some tests for Launchpad and obesrved the mentioned things. It is possible to reimplement RiscLua in a mix of BBC BASIC + ASM, but I am not so sure I’d got that path, I am NOT a BASIC developer, hence take my thoughts with a grain of salt, however: 1) I find the lack of structures in BBC BASIC very frustrating However, in 1988/89 I remember I ported one of my Forth compiler to the Archimedes using BBC BASIC (that is all I had back then) and the Forth dynamic compiler worked really well, so yes it’s definitely possible to implement programming languages using BBC BASIC, but in 2023 I think we have better tools, no? [edit] |
Paolo Fabio Zaino (28) 1882 posts |
:) |
Paolo Fabio Zaino (28) 1882 posts |
I actually started to write a uCLib for this, here: https://github.com/RISC-OS-Community/uCLib/tree/develop I don’t have time to finish it now, but you can see the test code gets compiled as Transient and it’s all written in C. I was about to add the code to get the parameters in main, I just need the time for that and also allowing a bigger chunk of memory to start (mostly for the stack) in the RMA. Recursion already works and, obviously, have to implement printf. I already implemented atoi and few other bits, also the Assembly part should work fine with GCC as well (haven’t fully tested it yet, but it does have the symbols required by GCC) |
nemo (145) 2546 posts |
Rick remarked
I once rewrote someone’s sort and made it 147,000% faster in the worst case. That was a bubble sort done wrong, a trouble sort if you like. It became a hybrid insert/quick sort carefully optimised to the data and some other weird system parameters. You’d think 147,000% would be a hard metric to beat, but Acorn weren’t involved in that. When they were… You may recall that RO3.5 introduced the JPEG code into SpriteExtend, and implemented the Compressed Image format of Sprite. JPEG-in-Sprite was very useful, but unfortunately they botched the code. ROOL ripped it all out because of course they did. Instead I fixed it. The problem was that due to lax checking it was possible to get false positives far too easily. In fact that’s how I discovered the code existed – I drew a Sprite and it suddenly turned into a broken JPEG! The Compressed Image format is trivial – the Image just holds the data length and then the data stream… but Acorn forgot to check the length word at all, and only check the first three bytes of the data stream too. If that happens to look like a JPEG then it commits to it being so and ignores all evidence to the contrary, marching through memory until it finally stumbles upon one or runs out of bytes. In fact, after those three bytes there’s only five values that could be valid (and that’s stretching the definition of “JPEG” beyond the strict “JFIF stream”). Putting those two things together – a byte length that can only be 0-3 bytes less than the length of the Sprite Image, and the fourth byte that can only be one of five values… JPEG-in-Sprite false positives could have been… 54,975,581,388 times less likelyFifty five billion. And that’s what my CompressedImage module does. I’m not expecting to improve on a 55B times improvement. I’ll take that as a career best. |
nemo (145) 2546 posts |
Paulo postulated
Utility entry and exit conditions:
Utilities must use X-form SWIs and are called in USR mode. Utilities are usually executed by FileSwitch, which puts the Utility, its 1024 bytes workspace, and some of its registers into a single RMA block (it’s not a good idea to mess with them). R7 and R8 can be passed from the caller only under some circumstances (and this is observed behaviour, not defined): OS_CLI: just R7 So you don’t need to preserve any registers at all (not even R13). If you are using Utilities as a plug-in to some other system (so you are loading and executing them yourself instead of relying on FileSwitch) then obviously you can impose additional entry and exit conditions. |
Paolo Fabio Zaino (28) 1882 posts |
@ Nemo
yeah that is what I though too. Thx |
Paolo Fabio Zaino (28) 1882 posts |
Today’s C++ Design Pattern on the uber old DDE C++ Today I went to implement a Proxy Pattern, to see if that type of indirection and interface can work on DDE C++ and, oh well, it seems to be working fine! :) https://twitter.com/PaoloFabioZaino/status/1631409699961667584 Let’s see if also tomorrow’s design pattern will work… who knows… |
Paolo Fabio Zaino (28) 1882 posts |
Today’s C++ Design Pattern for the old DDE C++ is: Prototype And also this one seems to be working fine (of course with some required changes/rethinking, but actually very minimal work): https://twitter.com/PaoloFabioZaino/status/1631754454566330370 The exploring continues… |